From 6f47305c597a0d0c946791532a02b53df56a5e81 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 16 Sep 2024 21:32:54 -0600 Subject: [PATCH 001/264] Add Filtered TMC TIM Kafka Topic --- .devcontainer/post-create.sh | 1 + .../main/java/us/dot/its/jpo/ode/OdeProperties.java | 9 +++++++++ .../jpo/ode/services/asn1/Asn1DecodedDataRouter.java | 10 ++++++++++ .../dot/its/jpo/ode/traveler/TimDepositController.java | 10 ++++++++++ .../java/us/dot/its/jpo/ode/OdePropertiesTest.java | 4 ++++ 5 files changed, 34 insertions(+) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 21a448f81..c9f8e5057 100644 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -17,6 +17,7 @@ bin/kafka-topics.sh --create --topic "topic.OdeRawEncodedBSMJson" --bootstrap-se # TIM bin/kafka-topics.sh --create --topic "topic.OdeTimJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 +bin/kafka-topics.sh --create --topic "topic.OdeTimJsonTMCFiltered" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.OdeTimBroadcastJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.J2735TimBroadcastJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.OdeTIMCertExpirationTimeJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index de04905da..bd7041c2a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -117,6 +117,7 @@ public class OdeProperties implements EnvironmentAware { // TIM private String kafkaTopicOdeTimJson = "topic.OdeTimJson"; + private String kafkaTopicOdeTimJsonTMCFiltered = "topic.OdeTimJsonTMCFiltered"; private String kafkaTopicOdeDNMsgJson = "topic.OdeDNMsgJson"; private String kafkaTopicOdeTimRxJson = "topic.OdeTimRxJson"; private String kafkaTopicOdeTimBroadcastPojo = "topic.OdeTimBroadcastPojo"; @@ -590,6 +591,14 @@ public void setKafkaTopicOdeTimJson(String kafkaTopicOdeTimJson) { this.kafkaTopicOdeTimJson = kafkaTopicOdeTimJson; } + public String getKafkaTopicOdeTimJsonTMCFiltered() { + return kafkaTopicOdeTimJsonTMCFiltered; + } + + public void setKafkaTopicOdeTimJsonTMCFiltered(String kafkaTopicOdeTimJsonTMCFiltered) { + this.kafkaTopicOdeTimJsonTMCFiltered = kafkaTopicOdeTimJsonTMCFiltered; + } + public String getUploadLocationObuLog() { return uploadLocationObuLogLog; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index f2b9c393d..e9276b21f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -103,6 +103,16 @@ public Object process(String consumedData) { // Send all TIMs also to OdeTimJson timProducer.send(odeProperties.getKafkaTopicOdeTimJson(), getRecord().key(), odeTimData); logger.debug("Submitted to TIM Pojo topic"); + // If the TIM was generated by the TMC broadcast to the filtered TMC TIM Kafka topic + try { + String generatedBy = (new JSONObject(odeTimData)).getJSONObject("metadata") + .getString("recordGeneratedBy"); + if (generatedBy.equalsIgnoreCase("TMC_VIA_SAT") || generatedBy.equalsIgnoreCase("TMC_VIA_SNMP")) { + timProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, odeTimData); + } + } catch (Exception e) { + logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); + } } else if (messageId == J2735DSRCmsgID.SPATMessage.getMsgID()) { String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); if (recordType == RecordType.dnMsg) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 56dea7112..32c87e474 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -202,6 +202,16 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimBroadcastJson(), null, obfuscatedTimData); + // If the TIM was generated by the TMC broadcast to the filtered TMC TIM Kafka topic + try { + String generatedBy = (new JSONObject(obfuscatedTimData)).getJSONObject("metadata").getString("recordGeneratedBy"); + if (generatedBy.equalsIgnoreCase("TMC")) { + stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, obfuscatedTimData); + } + } catch (Exception e) { + logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); + } + // Now that the message gas been published to OdeBradcastTim topic, it should be // changed to J2735BroadcastTim serialId timMetadata.setSerialId(serialIdJ2735); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index 49fc2125c..b0f2e9cfd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -93,6 +93,7 @@ public void testSettersAndGetters() { String testKafkaTopicAsn1EncoderOutput = "testKafkaTopicAsn1EncoderOutput"; String testKafkaTopicOdeDNMsgJson = "testKafkaTopicOdeDNMsgJson"; String testKafkaTopicOdeTimJson = "testKafkaTopicOdeTimJson"; + String testKafkaTopicOdeTimJsonTMCFiltered = "testKafkaTopicOdeTimJsonTMCFiltered"; String testKafkaTopicOdeBsmDuringEventPojo = "testKafkaTopicOdeBsmDuringEventPojo"; String testKafkaTopicOdeBsmRxPojo = "testKafkaTopicOdeBsmRxPojo"; String testKafkaTopicOdeBsmTxPojo = "testKafkaTopicOdeBsmTxPojo"; @@ -137,6 +138,7 @@ public void testSettersAndGetters() { testOdeProperties.setKafkaTopicAsn1EncoderOutput(testKafkaTopicAsn1EncoderOutput); testOdeProperties.setKafkaTopicOdeDNMsgJson(testKafkaTopicOdeDNMsgJson); testOdeProperties.setKafkaTopicOdeTimJson(testKafkaTopicOdeTimJson); + testOdeProperties.setKafkaTopicOdeTimJsonTMCFiltered(testKafkaTopicOdeTimJsonTMCFiltered); testOdeProperties.setKafkaTopicOdeBsmDuringEventPojo(testKafkaTopicOdeBsmDuringEventPojo); testOdeProperties.setKafkaTopicOdeBsmRxPojo(testKafkaTopicOdeBsmRxPojo); testOdeProperties.setKafkaTopicOdeBsmTxPojo(testKafkaTopicOdeBsmTxPojo); @@ -199,6 +201,8 @@ public void testSettersAndGetters() { testOdeProperties.getKafkaTopicOdeDNMsgJson()); assertEquals("Incorrect testKafkaTopicOdeTimJson", testKafkaTopicOdeTimJson, testOdeProperties.getKafkaTopicOdeTimJson()); + assertEquals("Incorrect testKafkaTopicOdeTimJsonTMCFiltered", testKafkaTopicOdeTimJsonTMCFiltered, + testOdeProperties.getKafkaTopicOdeTimJsonTMCFiltered()); assertEquals("Incorrect testKafkaTopicOdeBsmDuringEventPojo", testKafkaTopicOdeBsmDuringEventPojo, testOdeProperties.getKafkaTopicOdeBsmDuringEventPojo()); assertEquals("Incorrect testKafkaTopicOdeBsmRxPojo", testKafkaTopicOdeBsmRxPojo, From 286f17072dc86c0d526792ca6c4d7448fa93fceb Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Mon, 16 Sep 2024 21:35:37 -0600 Subject: [PATCH 002/264] TIM Dataflow Diagram Update --- .../tim/TIM Data Flow.drawio | 220 ++++++++++-------- .../tim/TIM Data Flow.drawio.png | Bin 252061 -> 293317 bytes 2 files changed, 122 insertions(+), 98 deletions(-) diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio index 7bdae6831..e05d5d54f 100644 --- a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio +++ b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio @@ -1,189 +1,189 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - + @@ -191,7 +191,7 @@ - + @@ -200,100 +200,100 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -301,18 +301,42 @@ - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png index 1c28d8e7f847d465c7a62394c1eee5ce873664ee..966c6c7b1c676d9bb64ded8567ef64ba7cf0ebdd 100644 GIT binary patch literal 293317 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

j zrWQ(v?n?E0iqPvpSFs=;fCLpoU{G&B0FXPexSh(LRt1rG6!uRTJ03_<*~|-uTfg2d z>Z{Zkz|I5B+5i^a)^9@ZzAD|`O8_`+2f*MHo8-Ohf>dd9vCaRTWGmJHL>?bW%mC*n zl*M>_vm2UFA+{EPY_qYom5o)Hr@J^=X{?OxVQl{si#l{IAtx8>Ha06EaxIhbOl2C;UWp^ z_;b^JO)Ej1a4E)VEct2(emN|vP55~TwX(m)Jg zBF-OR3LtULGIo=YkSMSh|L6fw)N}!;P?cJvh^JNqHwLvjnBHI{Wi(`B8VFgkT!WnP zR5o!#O9~1K5?We#0s;cV4u%>9GE=~PCEliP)@;oe49Qxm7+NB-~SF!Css@ECM5oFjKOIf{!9)~-t z?M7b#3{l|>E=Pq&-`F07ff#16SRvXInzexbIB8zhzjj9mGXSn7^%0FEFiQ5YgH)!` zTyu@vLs=Hf|9@Mcn?L4Ca{ZqcXyG)ygngg|8nwZk*P!&uZY=NykqqqJ5n%!h*gr=E zml#+aJB*YQtJ&-12yuN;S{&~ynhaps${Q*U$*K$)=m9w+B5)qq5GHgKs+3#`T^bVk z$fdM^BVdYQ^Xx1F_zQw|_j{!oZtvH&;iq{02Rn`bhqt#3>#FOzMF!2A zy1N^syE_DFrAr#5LAtv`q`OPHyUxPL`~E-gd(QcAz8o(u+?R^Kz4uyc&N0RuYfUXi zHqb>lU;1@#T28L1TIs-uW1W(=nMX)M4C%i7JH-IgLgnJ|uMdFc6*8oHUZ}8q4h78iE zMOOk5XYF2ok{`tHR5XjCAM#l>q!-g9SCb!ulg{f~+eT(o(JP~7Ffcbs59VpJwK@I1 zY@)Q+I5|@#x^Cq5x#Z)Qo-A6@9cLoZT<916nICHZ%nxG7+<|nVBu2sVyKolUC}+5L z3d;F+fahEOM(~p$hM*#mMbo3KX&dMgwafMd3Y~aSh++z}X%uHO?PF>mo#z`3#ejT# zb1Vk6$zA!W3NWArULR#;zeHuGd0yZ!GBS>*p%8HAl`9L!h;PS(CdLKSQ~eQi=dw~X zTwEGPgW{Ho9LkTNfvX;nho&n{qm#1m``F;euC83jK9ChE?IiZQXEXbZt72xDn_=WC zW2|$^Q~_dd+k-_+b3r$rH-!o6T@ITpSoRX|G59}{9FIxMC2-~Cr+dGz;X-D)M6={3-c(f@+LJzB9|6l>e zzgS?J2qK!dg zk^{RwY{b&%5*wP9?Nk`^T9?$f;H7BjTzKbLp{!y|WUIR63f_EUf!55reg1LJ7nkE_ z`1mPk)4#2*#`g@PcZ+^!V$-R->vGBe_~zL2;=|JdfBg^Bz#}8-8Qj1oBh$Uc)8rh8 znaN?j>1s6s1F0C&3fj`r0|*i8n3R$d7Rh@9*Wk2Yze?_r!?~U;*2)h(s_#sCJcvTx zD<#0+>$sEG?4K3wYn->F81e#vNF+a6|1mJSkPs3NF+k?CXXxnY84lees$S#o%c{Pw zMe%?1D-pc{^pAj0u}Xs~{CHrro0EmgOY%e`@gIY~pLmb&0Q3t4gdbK5oJvb-<(!9& zr_zlJtKBxcygo{6!{#|$ zo--cs*3EX!7S@Y)Bdp~V{OH))3w^qQTdBV{;KbkRfX-NH5(W7NMV&vo^F`K8z& zMk<<);oG@Zwd)lw$Wt{1D$|-|N zF<|koCQU(sS55u%asglX^KzYpfNnrGrU=Lx1n{&&f{3j_LKM&5H*{gArl3YcLnF2D zMyJKg69`U;9jH0dO!I)`Lbpd%sOpw^s+T*ma^X*73Af5UPb!Js{en6MD-6Z^!9Otb!B zML*#ZcAUg>^P40T^u8wAa6IGoZ{;j?x~OX1i1J}Uzgh_*q_>!+&(6&)F!DI*dv|p< zCS$wai*|n5a8Qo`PA3&U-Hf+}wU?SoSoy_M$aSsw>O%(Cdwj7M184aC1JOH{mmJ$zU!rZ%ewH-bIHLH3 zHqfPLHPL$4y0rCmK}r8SuyL>h>m33A^*692pxN0qQ@!NSfJi2*nh@FU$Bpr79r!r$ zfV$W_JizaDuo2m~r?_tXj+l=P(@MK)c~cA4su^kJ01w%@#YX9a&yWi=HeL4|`p?hM zgTg-TWk$JpTCETf zLQh4bp8gaM507#DmaA0+i60rt zWxq@aQ;S3$TYQ$4G*!$}YZT$)VnK?G=`UI+qr}D&*A}60`k9SHGvRV+lOH8!c zN>hb%ViNgsNn!b=H_J{|n;*jHAUBba5fNfDQXcQ{b#8y$ZltnW_ zo*;04ErfzWl)a}>D~G;Z@^0x5iGAej+gh&zo#+a~W+M3>u)&8bdRs3wH|<+cs=WWJ z&%Du{_=CoH|DrJ>h*(oIl+iQw@|e*W9YjF)Cf`3z4i1S0xxT@eqEQ4aT5P3tu6ihZ9NNjmg&q&0C zFZwS#fgaiBkHY)8sEFEPwlY}cq?k;WL*}m(R7Uy~7c5!-#)U6FBt(pIp=m~A(xz+s@WD!1c|{F)Pk zR3svxu^PY@GI5b`+)tp5e4%&E>B$MbLi09o8 zn|2&srPamsD81t!QACmCO;ylyNi4{ySlHQBjdF8ya`FxCP8vmj7Ql_oS+{5zReul` z&M%rUN%MRK2t#5)B;|d7m)r?QUy;!tUiP0UM*1i7V*MxcVnBS&`KGSzXS1GfvUZ+EB8!r?%4(Mjmqlzh`6b$p3 z(dzAdV`30d_1yNR861NZgh6HB2udJu<;v>KGp*^CFVSt5BoZ}LKOKrZ{4oqd{r7;&fKvM-^T(|?Ny03Wu({RuQf{@BSJuGn+QMq>9IuYA=`P*dRKEf+^QxN{=k3NIP_Wy&U|6olnyxc!a{3m2K5Wz?u(*L{##SZ)$!4I z0X1>(N6Pf7SFC^IB@u)mYVY7+KzuxwbSigncQ_uNzH~}}D*(ar7^4xpp`)WI6dc;0Y;Op6dGl`6~Lvuct>0g1>LXYp(XO zu`%`BAy;)`i0&jzE8Ooz@L<|W(Q7xLgN?^bt6Y>H_^H&yP1P9|FD_`o05j_xN-AXa z%8M(whq{!+|M@>#N1*}O_yo+-7K@EIShSk0fRp+G-BthL?mADWh4&S$=4bFPh}qb% zN}DclUJ1A5&0IhLv}6i9TA@nmhv>Ib zN4=zx{FAf>PTQl;pP(Y|)iTt%DMz={3!z3c+mz1y-FprWg!)Szj6#xLv_-l^Q%?TK6YfBQW{3wm{gYJB0u3;G;F8y^6#VG@ z?IqO=#fjZ~t*y)LeogFMGLuO}R2+$fFhM^W;00c)6S~$5^;IwZ|Bnl%koWSJAWH1@ zO(iVBDNB*?Isp%==zp|LafQy zEZ1Q4opg$G;ajU99(ebV?G^LTvQ-WE{C-Yh)axNLP5{>hndB4FW%2HdiZ!^1qM1z>fC3w{h?$u&(!6dc zU{DA&OXy<{XT0vuRnA@e3}dOa(3&j5Sh{grUWlfffk0W1*Vimi13%iWmCLu1th@D0Nsw#0OPXY<&QMHggQ)Le8T1$X8o1XVgOx{CA-J%Lg2wfL0M zI}-JX86eIsAEX{ZkEH$At5c@8qI9I;miz`Nla zOQo_?5v67tyNjCnCjVWrTzDfUBaANbM^qi7pmV`i=<5+I;hZ^g~!{u2k|k zzJz$u|BHMY`&dx$89W)oBqgDmN4xS6{-I4`_cUrwF-Tp3q(QG3R$K+RqdlzFpgIaOu28K8hr{$ zUIvF|R9L2z?Fx*<1$L(2ss_MQdujbm?Ep)xZ*8rO=PT^EG>${i%&bRcfvO}KJJm@& z{x%9C;#1;&1Et6dV0ckLA^wcBy}g2?5}+YknuJy05mG{XM;aTs0|El_6oTa4_#ZTt zqr+6{uEfl0#AhH_J>eCNN(Vv(x|5pSdqzb0sQ`OY|Jo?dr%q@xq1TV!?gt%40>NCQAw(XGFPTK#A8XaFBJIxo@2to&^QjW5h<24McV2PG zE@*6XM3|TKpqLEG;-ck}iCP8d7E}b?AD^B-#J_J)0Skf>=er%wcvVs{81ymoeRjTo zX78j}dRZCjlZ$I?L3wjR+ge&08C1)cxBJk2Cjw24Ueiw& zS#+>#z04zlXu!(7=AaO5sf5L`b^nrT180@mc63&ZAhV=?bOi4oEph&6qTba+arwiq zks5dliJ8tx7!`&|-!Ty^3KXv>RX{bGJNQ&2r%ei$^D&{7u>#O(mdjt}Yn3w@uL*PB zjc1)VVWEDB5a;Q(f0N5vcD71}h~tT1weQWO?S1d4q5f*>AGIWq6z-#EPKS$HjS-+Cy8>L~LJRfr zG6#K9=ZlMrPj1@zg@p<8o`~0iK=k+$6$J?lLP_GrrrK}!q~nrUf$Ix3qgU)d^L&~f;;X71PPArTgFz3n!{OrVWH##$Ap6;X z1RXW=rY}T6f6fAg#$w5LR{I*``J<1Mda9EUl zW;F?o6`hB9rJsy0J1E*?yLuNe*MOqEs6-h5PEN;B{tU90UemHxg=g%|s^BKE?*3EU z;kMP=ZZ`04NTcC{!ureJ7dV(?j4c`FiSbG$%BwA}YAvVOyU2=64n)m-6QN+FI7; zRTq|yE-aOe6iccJ~^#Gm91gB+dcQs z8rv{^Cc_dx-Q=?@7Kcx~O2?^PN;+vfO zh$l;e($FY}{pOwd4A5)49jCN{p33xklqY9ETM_>70mkd@xX12Oei+BcUqt7}p#ES0 z%(zzox5jYCnrvJ>f)aPkGe=(^oZfoO;bG_cni_D)XSU^mD(+lu?e zp4?Iy*b#E8b6(${3}s|GV+e}7xK$p6fBC**3cpw|nT*(fi>VY#J^%k|so*FFU9dV` zK!o`k8~X_i>9MF+mtfB9p+AQJB98gj;Jql*12utB0G@cY!%o$J5CDKGp5-Bow zfzCV+blR$>byk(@O^wbxO?@Jf>GkCMCvyU+;fa4Bz6l}aP~}GGXMDTgR)TJq2URNbpN+@d!2I( z&d5Fn;;n$88bHJYMS5m0bE7t9>K)A;JNd}TMZ<}Wo@MhEh^n9gg(KEu$q4*)24zdH zcC$y_jkeS#wPo)Y;*S#rv2NPsG8^vH`Gu4sj~m#$z^K_Gi)|jpaw>u&QuY>-l}u7N zraMg=>G7A-(-}G@Ds<+v2wGc7Y016;c|4*KGeOHA{A1XSm!TCqne1Snn2}*V7y38!AM>-+5)lenLs(_dhKkHT7@D^K%+`CMf{qsig`>9 z=G<%Xu@KwUhQB&YIyI!7ZM5d(n^EAP3f!p-8$ZK9qfCr1DJdzq$jkr6VgI2?CZf-J zzE*AmkA{MI!?Wf70`EyT06sIIjFNrI?;QtFE06b$Ju?~EhR$~@pkbQ@i%ETxGSSh=+%u|{ zGjH7DUAqIN=vS4wild~Cmw?CrmXx3NUKR*Y?whqM1{53SzyN>7Vb192=s1IytM(fc zrGRbVgDYXw$jZ!AoGge@z5xtM(Nl3-g*GB;Sj?Cvxf;OYFcwSFkR~-Qh{9L7VAsTF zo}1@(@}#m^+A3fZO!>uq+4S8Qy3E>W-8Y+4BoWb2G#k4O22UE+j>RX0^-3;FiZF_W zc&T;Z2XkF*s{{Od5OXHNi$=4bws3^q_zL{p!LbvBczp^AoC7I{My3-NpGPar=C3gR z#-d&{*FH)XmO38o=Bcm$txY$p)cr@BUj6X@Nt>3J(2j5prRQqQ z+YkZStMCSo$v7-YB{tX!tbqTiq(VZ^19Mkiw zW7Gdcnp-lW4Zro;CVUkvG_~?RIWuDc-wEk<9?1#A&XBcN9S;+*Lf>j=AH1f4Nv^uLowtH5&}X8D4vE`2gV|x zXHQPX(P)fAb2;t=U{WbRdHpC)-&9AlZ+uYUXjU$li!-Yzjme$0F{Jw!>;Jvb zrG-=`lRPb7wLLzJT-ni z&5ex0I7yk=uF_NI{d>QH?_?|z5|bpcYkFYokT5{*NvxIyR>>?Zu3EI5nnG3MR=0AM>pYQ4~%W(CQ5*-jnZcRwimED1H=vNfPZT*Wsak0J@tE!X`YS?Gf z&=CnTCdUXWlX>D&!epaAHi6H(xt_)8d}m^UAf>!=7H(h<;L`uHYyV5b6ytrA;KnKw z_)x1JNyn{NQJdSO3LA`hb;Ka^kKdts-oXZFJ#u@z=TbQ_y>;aRdFC={RI#P>6A%E2 zczLy7SCm?LQuWK99^mEVyIz+&|Erk)!+T#qbRdkyIsu~z{b8ZDEF^u{!i4-ghr$R z`nR|6-bkrz&BlVwC35laq$^$~v|j1RwrkQt)X`O9a14)Lu3S;6M*nF4K2DD5hKt(H zLQKw0)OY5Ics7y$s#g8ESKmT3`XYL%$Xf(CSmO-s!rSE)h0unNsF1+eV|#F97f|K- zYLSHt*HAew83qK1X@w-^@MLWnxwswSn|@nzDVmONSyBJ1%)xI88HkZPLxIMAdTUNu zF+R`&;XI@Z%@{SDCpiYgCLP$IQ`=_zeaV4bqOd0kY@oawJgBGR)GAn{dg)JD z6+xcV^_`Ry5>+#Hz(&q)HW3K!erT9GSsz5NkaY1b&Gd$Vuve`bZ`2%yiAxi7uYUc4wr-v=uCXxcvCEgKGw>^J?F)odgI>Rx;yXC z(Oe(id_eX@9_G2xIS*@eJ{h!S_q<@YYW_jEh|L8B;Uz$Bol+Riw;SsG!|r|xls!cb zt)S>l2XAfc9NLdRcO;xW*w@CO`ny{ZMhNy?uAF1#W;uy2*!7fBK8_B{C7B6F-Tyo5 z|6cHKz+;OiyiHXLJxf@UEuC2IFAb1U4QQ?FSZd=sdkf8qt^4)(oFJxroVyc91szqH zO-X`raj$Y8HO?TaAFr9T3GR`-X3o)bJ#Q#UoQ*psCW>8>POdYuth;=){cTN_ZjYBP zQw2Qq@fY#A6q>fqw+)V_>Q8N)oZ8Mk1&@E<59{+Ex*u<=91`=8Vp8$lVs3<2=x!G= z_C&HfLtaK6_+LJ7p?L8^xahZgCfxKt+T7AOXAOJLW=fr2{GMBrX6at^Z!wq)$vQek zB6q$EVJz*v1sM8$@Zmp&<$u@XK0Nk^giT{jq0S4ek+KC+n^VL|ubjOR>Zj8V(CQ8) z0-PUFOSG#!Ik1fK)!ygTDu^qbp3sy!+xLx*wmYm=evh?Dx!!!wj9~p~0oF@_akOLM zRHyxHJOc6jX1b4531)j|*!f9@aeMa zC}4Z?8(%D!*HF5w6kF7&qC(1E*k8c%Z*-s(YNc;yHam2;xjYk;#kSTi{q+;)w-mgb zH!&B}bG>~X#$QF1-(G--%RR6gKB`FgGgoeq0-O#%7HW%iG)^TLOI}R)DxxQ_$p=j^ zwNAe+O7CW{u){{zpvdih;xhG9MFrEMi*4YIdj&zWD!nJmq_x&3y11bStfC&T%jFaO{eEfjbhSB@^5E@8`QYHN|CzVvfHb@3fl%Ta2F9zH>zh@j)3UAQ z!vrQH_?_{B$ailM<#5Wv@tAwAY6v^N>O?8>jMZL+estEbB$HGr(a}7(iV8Q2_+V;= zT(B4YzsIQmtuCCNo70pKbU?MAwT=BjbnHvuV+_nr=*U|#3W+UA-!oN+Q#a-U3vNIQ zMGc%(!^`P}s?J=8Oc$0Ea5l(Xxq}&i6ndHISm6}=DmQBXx|QjE{Me%o+w7;x;o87P zn(puoIrqb8lTidIgVN;H;ZS0>(9Rs)ki5wKq34}(n42!*0p1a+Reb||u2f2B!_8tO zMTJhA3e_gL9xkSR$^7xRZz)67t}(gBf&&qMD`EeXZAF(~K)%AtjncyPwu1*-?P4?x zHvVk11LoaX$v6t5?MH({+Vm_=+!|j#eh_F5pq<5SzkgX)4~biqou>f4K-#V*Ra>}> zu7%fr8ZV=s5yL|_TjxG5um$uUymdcZY#Qd-;<1)Eczr!Y&2j5+5LS;Km67jw7yCj& zc=tAP*QYf-GJ(g9MLNY^Bug4IytHX5e-v9Gh~_>wI=6^ki@_7NAH%*Q56832W#5}h zM&YeY`1RUkmc?-h+9bN%J;8V6-Y-g;6j3?vyUJNMb}wM3wA!_XlM^cRA*~jhAV(Ip zVA)nWFWh@m7~BKSHB81IR0_y4^07~W<4v`}lsXL(BmLQPa(;*xvOeI_X8|sc030#G z_3CFI6S3INos)mTRK!(NGqQJDj|~N{;wdzugrxx-PEz+CJ2_5V;M9pT;ob3B-FHNM zbk4USPFsyj&24yTD!n^VP{(Uz^l?~nJZSf>Ha4i*ZahH}_0%V*6mnKY(?4uZ8et0> z9{lKtiOW-0s~A^Cwq@vxNW$|TJ~~r}KuRJ>b-6_1bI3nL`sP=OeA-ZWy1jqz^x{pr znJ(_#3J1YA+=vu1&bjFPl3TmWK}bVd7Tn{PIa5U)Wo=nUBY0O?P%4Hq?L;BJ#u=W| z8*}%Na;{}Ksp5XCE<7%B*^Sw!%k{c<$PX0=sXz^FQr?}iu+r2rQwwIeRh<6CY#~c&wze~x zz+z(hU(X6YhWF`X2nh}&nG*+y^j>0le%wuuhwzd)+8Kd2q~TJtZ!%Ifn-lE*HC}$q z5b$yMr)_M8kze(F44l;3Tj&S^o);Y^3+nD{=;(2EFH=-qpsSMN;-Lh&glR}8ZG%pD7g<1VJ25K{e zAXKcFGQv%*?5Mi7Rt6`s*qz#62kLU4b&&AygBmlXV%cyF`~3WT?SfBV#V0oT|1p%C zaCxs1Zd%ykAHUyzWsvzMI=8#O76fcp#A@;;_BUPbN*FF~pw~T&kOzq`nG(29W$+#NXuP$n6$KFQvRKSi9^p%u zu85>A3YNH48bx`}4ki&>Sc(Fdmt{Vul{3c;6GpHOdBH@V7<7tca})3{)Yv)|Zs z9sekYsDjcYaFR{YLa|hA>oxCc({W{z*{D$tx$mDzApo6$mw(9ErK5U$>4@%n?a9r`0(i zvhJ(HfA19gbx@P~dpxr=Uzoy9M@Y}~cfX)FOsDzoMQwYMZ$8ObcK9aNEvS^Kv3)0pcGArjN_y9$UP){rM?=kJ-rE$-)WVX&ID-BP zk9@Xu6FZ+ZIT#JjzDUc(eIMU*x%$oF=jZqJoysc=>QlVHi(8&i8^%Vbs$EtX0fDqK zH?cw3T+ru3uoPm<=CMBlPHgdd-v2P!-G+iyh=MhACpfrFQPBcUa(K@x;OhA0GF9{H zWK-eC(VQ1B4md#smatimwa7=_hd~VY#-sv`(CjuASZ;{czAP1&?ZuLgI0+A$=PC}S zGfUI)18hGtj0aY0?T%RF-$~WW&QLzpCYb4?(aM&4T z6M#{U*4y11DKwfx*rbB#frh7HWZuY#^o1Z-WT7#RR13H3qS6~I@;W-dY-@+dlXB&5 zcW+0K>Tsu-nJ**HL}hHGS74^iyd6Sf5>{LJr2e%@+ENTIH+Jgu{%&dYA#09YK3%bL zGnfJ;2w8HgB!%4n9v*6ItvHR1lI0pLh)r8Kb&oGWK4#*Ofs7hy0q!^v)qaHF^2Sit z?0mcX#ec8bbPb3J$T8R+H)6p9+|Ox8bFudNZw_8cVblKO1>kY#%w8S&!%`(~oV zP%3qn;_$Jpl9j;`rEaCX-T26OMX@eYIrmg#1%g1rV}daX(iJkSX-JScV8cDa`VgC+*nn--T$#~>_k;hnTjTjw^_ z5BoKTnV_}rv%S)KEJxj#T;sJ4Yx^FJ2tASIoJ8ExwaXzSr$iRHfwn z2q$?+h;p^*czUxxFrX9@9Yp=1t-$nGy`0LK72o{Flda9`-n0hPkbBkc%+|BZw>-b< zZB-0h^*?EjSxwm3Z9y4|r(wpIq_zD{^fdat4muQlxJdLh6q9d7O^_yR#+RyBZfmsN zrPuX%SJz%8Ftl0TSnNL8df%x%__~3$-H!D@)3;}saCKwXtA|ligZbsw1$Xep9eqGlO8p)jvUvi4CwV@}#Dhs7823N{Dm z{yaIh)7~6R!uoWA1sXxx{%SU*8@E;=7{YVtT&)^I!@&4#WeL;w_=TwCGcVLCrpJ#E z#iFa93A7dSBx|56nA%kDws*SIM&OA(#X~B!A`Q)l^Tc4Cf_vl4l5;C2HtH&E35zU4 znA~axWQ*tj2eUnUz9;vTxPN9;_iAU;tajde@pTNR34Uo1^=v$LqteO85-_+f{}g_k z(CoI4Zq@4AxkgPnv5nYbLQreF3jyYc{}c-H>UPBx`H2D(ck?kD<3{0gy5Wu^k30OX z{+iY?4R_!gKs9nDVJ@0Uhc%Yj4r;6`&y9dy(%X!gGLX@gk&+mBsO?2CPt;oOd!6sGVQL2naU{6EXM#l#ztOop^%X;qS zbS<@L0w>v34VCqdwk@yi^;bF>R)>8ic&$0MkjjOih*W_f0t2HX>XMer$54X%+~u9^ z@B|ib9^;=nkxg^PS)y%6I{C=gXK0sn)FLJQ1C}RD=+S!lztf57d2TNaa1y*8?%=UX zzI7jZ?&`H&A=z!@sp{2Vl#=DCG*M_us0bdv-}u5I$eI;NMkUz+ldC`6WnqN>!|j3q zqgO$wWXIyx+c>nmv=sdGZ_!UU7A$mf9!^n#P~EV{?YAt*0l0r&7>%y8cIgn zCG&9_dAfEPbkSjv8mPY&uHc;*n$8(Iy&koiOE! zT*X0z+1VL?nrL@>&J@Fs@A<$!qgm}lw6E!J^PeH`s`XxPBP<#(7AURBy2%}0BTBSj zndpMrj-ls&W7%JkK4!k##hxw1&WU`eRLXlcRl?-;X7^SgSz@V_EW}=(9n4}V^qjZj z(Jk3P{S1w_9?(6TxQ7x=>J&RLs5jZQ&}?xf)Sp?xdDWUR!Xk|lki zD;PgjGN+m?9Xogx@^~`A#bDYk4l=eZ7#PBF`7VTBOfilZ4g zxwq%~Af*`=q~hGyI$nn9d!_bUE-qOvfSy>?_&he>YlXS$r}z1k&PZx zIkz$D@q8C+o|oaZYe8vEos7I>P)?@*%Dx`u1Gh@G$8^gkBq&*+pc$7eH6yyu*Q{L4 zkdEef^id}8c{ORCho6-_)B=E90RO_-Cdq^s9a7KMbpe!h1JwPx4FC1 z&JJ8|$kxHT2fW?>4xN;3I$SCr`q%S~zTig(ZDT7ZadyIXrsj|!Vp54BeGiDlW@z8s z%%oxNef559A&50=t+ks`lTIz0`+&EWxT9|lr34RZ%om-LR3kU#_pd#azR7YGOZIot z`Y9dBSOfxz`c^K4N62*pTpb1jQnhK*SS$0d*$Vlh-bs8yYx>@IGJ9V5xU^K50jY4z zVL4y-@}h({i1754l4C7)T;T9DsT^ zu4ivr(d?JE9tj>E2)}SAGHpuk6YA;W)^q<@J^$I%vm^=gqu{iAhKA7vqflAljf{TL z<#)zUw%a?e4MpQ$jJ>>1 zMd9BR7tBa>^q8=UEJYgdT3pO==b`uVUG@!Z!!f@38Q!ZVdQfBF=vq9L?m#5T4s+*C z$?aeDW1?A)DZ+RR_KTd+Pzp^Y^hgas`Km1HRd>UA8pXky3$FS-_tx4Shg`X@8yB0q z`?t9moSeLI^h=WJ=B|!0OOHaQe7i!1%2Zsy`$u;?$}Vy7*sPc*9ba4bvQYC-KWbMx{ZE3AyO!T4sT{`agq} zrjOUUd-zO{^?KK>elNLFGaB`pAxaL64@E=_-S!sacar&e*xDoz)3fZ&QF$4|NjeiQ zzFe8N9M8|ZL&4ei+NBsk*D(J4xQxn4|C%)?h+9=^Xd(wuf;6oGQ8Men;uQHmn%Li2 z(aQM5BYH2M(m_ZQpNaI2|IZe-0DnRJJw6Zd5^S(x8RBGXh!#rWIHYMh{`5ZRSskR~ zN_jE+<1p^pVv-5nypKyPk7L1l_mRx}Zp=Xo>efaRlxQ?(9Rq!M5%-UJ$FXYv6HM

h|cB1NJYt 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

WAn=j) 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

Fv4B4n3E^oOBiSnM(*hcKd$Z%^?Owq54Vay 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 Date: Fri, 4 Oct 2024 09:49:01 -0600 Subject: [PATCH 003/264] make asn1 field optional for TIM as the TMC created TIM messages won't include the "asn1" field --- jpo-ode-core/src/main/resources/schemas/schema-tim.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index e9343d1d7..dbab9d350 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -107,8 +107,7 @@ "serialId", "logFileName", "odeReceivedAt", - "originIp", - "asn1" + "originIp" ], "type": "object" }, From 7934c9dd597712a763d242820cbe541c465bd188 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Mon, 7 Oct 2024 22:45:00 +0000 Subject: [PATCH 004/264] add oracle java extension to container for better indexing and code navigation --- .devcontainer/devcontainer.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 078e5fb88..3a9f04290 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,7 +24,9 @@ "redhat.java", "redhat.vscode-commons", "ms-vscode.cpptools", - "ms-vscode.cmake-tools" + "ms-vscode.cmake-tools", + "ms-vscode.makefile-tools", + "Oracle.oracle-java" ] } }, From e0ea7561d3ffcd5cf7901c14cf80a57c4d006312 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 9 Oct 2024 09:59:02 -0600 Subject: [PATCH 005/264] make build scripts executable --- jpo-ode-core/mvnw | 0 jpo-ode-core/mvnw.cmd | 0 jpo-ode-svcs/mvnw | 0 jpo-ode-svcs/mvnw.cmd | 0 jpo-ode-svcs/run.bat | 0 jpo-ode-svcs/run.sh | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 jpo-ode-core/mvnw mode change 100644 => 100755 jpo-ode-core/mvnw.cmd mode change 100644 => 100755 jpo-ode-svcs/mvnw mode change 100644 => 100755 jpo-ode-svcs/mvnw.cmd mode change 100644 => 100755 jpo-ode-svcs/run.bat mode change 100644 => 100755 jpo-ode-svcs/run.sh diff --git a/jpo-ode-core/mvnw b/jpo-ode-core/mvnw old mode 100644 new mode 100755 diff --git a/jpo-ode-core/mvnw.cmd b/jpo-ode-core/mvnw.cmd old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/mvnw b/jpo-ode-svcs/mvnw old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/mvnw.cmd b/jpo-ode-svcs/mvnw.cmd old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/run.bat b/jpo-ode-svcs/run.bat old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/run.sh b/jpo-ode-svcs/run.sh old mode 100644 new mode 100755 From 28f273b0b3aea31ee35fae9c0041757d12a82879 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 9 Oct 2024 23:16:25 +0000 Subject: [PATCH 006/264] track count of tims ingested and use runnable to print out warn if none ingested --- .../ode/traveler/TimDepositController.java | 3 ++ .../jpo/ode/traveler/TimIngestTracker.java | 30 +++++++++++++++++++ .../jpo/ode/traveler/TimIngestWatcher.java | 20 +++++++++++++ .../traveler/TimDepositControllerTest.java | 13 ++++++-- .../ode/traveler/TimIngestTrackerTest.java | 25 ++++++++++++++++ 5 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 56dea7112..fc5b4c22a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -62,6 +62,7 @@ public class TimDepositController { private static final Logger logger = LoggerFactory.getLogger(TimDepositController.class); + private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); private static final String ERRSTR = "error"; private static final String WARNING = "warning"; @@ -261,6 +262,8 @@ public synchronized ResponseEntity depositTim(String jsonString, Request return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } + INGEST_MONITOR.incrementTotalMessagesReceived(); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java new file mode 100644 index 000000000..d129cece4 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.traveler; + +public class TimIngestTracker { + + private Integer totalMessagesReceived; + + private TimIngestTracker() { + totalMessagesReceived = 0; + } + + public static TimIngestTracker getInstance() { + return TimIngestMonitorHolder.INSTANCE; + } + + private static class TimIngestMonitorHolder { + private static final TimIngestTracker INSTANCE = new TimIngestTracker(); + } + + public Integer getTotalMessagesReceived() { + return totalMessagesReceived; + } + + public void incrementTotalMessagesReceived() { + totalMessagesReceived++; + } + + public void resetTotalMessagesReceived() { + totalMessagesReceived = 0; + } + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java new file mode 100644 index 000000000..bfe2b3203 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java @@ -0,0 +1,20 @@ +package us.dot.its.jpo.ode.traveler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TimIngestWatcher implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(TimIngestWatcher.class.getName()); + + @Override + public void run() { + Integer ingested = TimIngestTracker.getInstance().getTotalMessagesReceived(); + + if (ingested == 0) { + logger.warn("ODE has not received TIM deposits."); + } else { + logger.debug("ODE has received {} TIM deposits.", ingested); + } + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 911a77919..5cecdb3d7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -15,9 +15,8 @@ ******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import static org.junit.Assert.assertEquals; - import org.apache.commons.io.IOUtils; +import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test; import org.springframework.http.ResponseEntity; @@ -38,6 +37,7 @@ import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; import us.dot.its.jpo.ode.wrapper.MessageProducer; + public class TimDepositControllerTest { @Tested @@ -167,6 +167,15 @@ public void testDepositingTimWithExtraProperties(@Capturing TimTransmogrifier ca assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); } + @Test + public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { + String timToSubmit = "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; + Integer priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); + ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived().intValue()); + } + @Test public void testSuccessfulRsuMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"sspTimRights\": \"1\", \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"sspLocationRights\": \"1\", \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"sspMsgTypes\": \"1\", \"sspMsgContent\": \"1\", \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java new file mode 100644 index 000000000..c88b900b4 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.traveler; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +public class TimIngestTrackerTest { + + @Test + public void testCanIncrementTotalMessagesReceived() { + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + testTimIngestTracker.incrementTotalMessagesReceived(); + assertEquals(1, testTimIngestTracker.getTotalMessagesReceived().intValue()); + } + + @Test + public void testCanResetTotalMessagesReceived() { + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + testTimIngestTracker.incrementTotalMessagesReceived(); + assertTrue(testTimIngestTracker.getTotalMessagesReceived()> 0); + testTimIngestTracker.resetTotalMessagesReceived(); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + } +} From f2e5a3df4b2209647bd49131399060e8f1487124 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 9 Oct 2024 23:58:55 +0000 Subject: [PATCH 007/264] define consts for env vars and execute ingest watcher if enabled --- .../jpo/ode/ConfigEnvironmentVariables.java | 6 +++++ .../ode/traveler/TimDepositController.java | 10 +++++++ .../jpo/ode/traveler/TimIngestWatcher.java | 6 ++++- .../ode/traveler/TimIngestWatcherTest.java | 27 +++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java new file mode 100644 index 000000000..57e64fcfa --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java @@ -0,0 +1,6 @@ +package us.dot.its.jpo.ode; + +public class ConfigEnvironmentVariables { + public static final String ODE_TIM_INGEST_MONITORING_ENABLED = "TIM_INGEST_MONITORING_ENABLED"; + public static final String ODE_TIM_INGEST_MONITORING_INTERVAL = "ODE_TIME_TO_ALERT_ON_TIM_INGEST"; // in seconds +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index fc5b4c22a..1f64caafb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -19,6 +19,9 @@ import java.text.SimpleDateFormat; import java.time.format.DateTimeParseException; import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import org.json.JSONObject; import org.slf4j.Logger; @@ -34,6 +37,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; +import us.dot.its.jpo.ode.ConfigEnvironmentVariables; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; @@ -106,6 +110,12 @@ public TimDepositController(OdeProperties odeProperties) { ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) : true; + Boolean timIngestMonitoringEnabled = Boolean.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); + if (timIngestMonitoringEnabled) { + ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); + Integer ingestMonitoringInterval = Integer.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL)); + executorService.scheduleAtFixedRate(new TimIngestWatcher(), ingestMonitoringInterval, ingestMonitoringInterval, TimeUnit.SECONDS); + } } /** diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java index bfe2b3203..2caa05141 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java @@ -9,12 +9,16 @@ public class TimIngestWatcher implements Runnable { @Override public void run() { - Integer ingested = TimIngestTracker.getInstance().getTotalMessagesReceived(); + TimIngestTracker tracker = TimIngestTracker.getInstance(); + Integer ingested = tracker.getTotalMessagesReceived(); if (ingested == 0) { logger.warn("ODE has not received TIM deposits."); } else { logger.debug("ODE has received {} TIM deposits.", ingested); } + + // After checking the number of TIMs ingested in the last interval, reset the counter + tracker.resetTotalMessagesReceived(); } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java new file mode 100644 index 000000000..23b1d48fa --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java @@ -0,0 +1,27 @@ +/* + * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license + * Click nbfs://nbhost/SystemFileSystem/Templates/UnitTests/JUnit5TestClass.java to edit this template + */ + +package us.dot.its.jpo.ode.traveler; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +public class TimIngestWatcherTest { + + @Test + public void testRun() { + TimIngestWatcher watcher = new TimIngestWatcher(); + watcher.run(); + + // we can't easily test that the run method wrote the correct log message, but we can test that it reset the total messages received after running + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + } + +} \ No newline at end of file From 2873c2ec3beae75fa5955404fb30918e80628777 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 10 Oct 2024 15:43:19 +0000 Subject: [PATCH 008/264] updated README and sample.env to add support for tims monitoring --- README.md | 1 + .../java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java | 4 ++-- sample.env | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 765981547..8a6085d07 100644 --- a/README.md +++ b/README.md @@ -287,6 +287,7 @@ Copy the following files from `jpo-ode` directory into your DOCKER_SHARED_VOLUME - Copy jpo-ode/aem.properties to ${DOCKER_SHARED_VOLUME}/aem.properties - Copy jpo-utils/sample.env to jpo-utils/.env - Fill in the variables as described in the [README](jpo-utils/README.md) +- If you want to see log-based alerts notifying you if no TIMs were ingested in a specific period of time, you will want to update your `.env` file to set `ODE_TIM_INGEST_MONITORING_ENABLED=true` and `ODE_TIM_INGEST_MONITORING_INTERVAL=`. See [TimIngestWatcher](jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java) to see the log-based monitoring provided. **Make:** diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java index 57e64fcfa..9992afeb6 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java @@ -1,6 +1,6 @@ package us.dot.its.jpo.ode; public class ConfigEnvironmentVariables { - public static final String ODE_TIM_INGEST_MONITORING_ENABLED = "TIM_INGEST_MONITORING_ENABLED"; - public static final String ODE_TIM_INGEST_MONITORING_INTERVAL = "ODE_TIME_TO_ALERT_ON_TIM_INGEST"; // in seconds + public static final String ODE_TIM_INGEST_MONITORING_ENABLED = "ODE_TIM_INGEST_MONITORING_ENABLED"; + public static final String ODE_TIM_INGEST_MONITORING_INTERVAL = "ODE_TIM_INGEST_MONITORING_INTERVAL"; // in seconds } diff --git a/sample.env b/sample.env index 9cbb1645f..c950db233 100644 --- a/sample.env +++ b/sample.env @@ -103,4 +103,8 @@ AEM_LOG_TO_FILE=false AEM_LOG_LEVEL=INFO ADM_LOG_TO_FILE=false ADM_LOG_TO_CONSOLE=true -ADM_LOG_LEVEL=INFO \ No newline at end of file +ADM_LOG_LEVEL=INFO + +# ODE Monitoring +ODE_TIM_INGEST_MONITORING_ENABLED=false +TIM_INGEST_MONITORING_INTERVAL= \ No newline at end of file From e2fa2f25e07ce858117d5cefddc54aa284936e65 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 10 Oct 2024 16:05:13 -0600 Subject: [PATCH 009/264] move ingest monitoring to deposit controller --- docker-compose.yml | 2 ++ .../its/jpo/ode/traveler/TimDepositController.java | 13 +++++++++---- .../dot/its/jpo/ode/traveler/TimIngestWatcher.java | 9 +++++++-- .../ode/udp/controller/UdpServicesController.java | 8 ++++---- .../us/dot/its/jpo/ode/udp/tim/TimReceiver.java | 4 ++-- .../its/jpo/ode/traveler/TimIngestWatcherTest.java | 8 ++------ 6 files changed, 26 insertions(+), 18 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 7b5fea135..82959644a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -40,6 +40,8 @@ services: DATA_SIGNING_ENABLED_RSU: ${DATA_SIGNING_ENABLED_RSU} DATA_SIGNING_ENABLED_SDW: ${DATA_SIGNING_ENABLED_SDW} DEFAULT_SNMP_PROTOCOL: ${DEFAULT_SNMP_PROTOCOL} + ODE_TIM_INGEST_MONITORING_ENABLED: ${ODE_TIM_INGEST_MONITORING_ENABLED} + ODE_TIM_INGEST_MONITORING_INTERVAL: ${ODE_TIM_INGEST_MONITORING_INTERVAL} depends_on: kafka: condition: service_healthy diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 1f64caafb..1cf03547d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -21,7 +21,6 @@ import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import org.json.JSONObject; import org.slf4j.Logger; @@ -110,11 +109,17 @@ public TimDepositController(OdeProperties odeProperties) { ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) : true; + // start the TIM ingest monitoring service if enabled Boolean timIngestMonitoringEnabled = Boolean.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); if (timIngestMonitoringEnabled) { - ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor(); - Integer ingestMonitoringInterval = Integer.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL)); - executorService.scheduleAtFixedRate(new TimIngestWatcher(), ingestMonitoringInterval, ingestMonitoringInterval, TimeUnit.SECONDS); + logger.info("TIM ingest monitoring enabled."); + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + Long monitoringInterval = Long.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL)); + + scheduledExecutorService.scheduleAtFixedRate(new TimIngestWatcher(monitoringInterval), monitoringInterval, monitoringInterval, java.util.concurrent.TimeUnit.SECONDS); + } else { + logger.info("TIM ingest monitoring disabled."); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java index 2caa05141..d9270fcb9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java @@ -6,6 +6,11 @@ public class TimIngestWatcher implements Runnable { private static final Logger logger = LoggerFactory.getLogger(TimIngestWatcher.class.getName()); + private final long interval; + + public TimIngestWatcher(long interval) { + this.interval = interval; + } @Override public void run() { @@ -13,9 +18,9 @@ public void run() { Integer ingested = tracker.getTotalMessagesReceived(); if (ingested == 0) { - logger.warn("ODE has not received TIM deposits."); + logger.warn("ODE has not received TIM deposits in {} seconds.", interval); } else { - logger.debug("ODE has received {} TIM deposits.", ingested); + logger.debug("ODE has received {} TIM deposits in the last {} seconds.", ingested, interval); } // After checking the number of TIMs ingested in the last interval, reset the counter diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index f16c657bd..cd446a77a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -7,12 +7,12 @@ import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.bsm.BsmReceiver; -import us.dot.its.jpo.ode.udp.tim.TimReceiver; -import us.dot.its.jpo.ode.udp.ssm.SsmReceiver; -import us.dot.its.jpo.ode.udp.srm.SrmReceiver; -import us.dot.its.jpo.ode.udp.spat.SpatReceiver; import us.dot.its.jpo.ode.udp.map.MapReceiver; import us.dot.its.jpo.ode.udp.psm.PsmReceiver; +import us.dot.its.jpo.ode.udp.spat.SpatReceiver; +import us.dot.its.jpo.ode.udp.srm.SrmReceiver; +import us.dot.its.jpo.ode.udp.ssm.SsmReceiver; +import us.dot.its.jpo.ode.udp.tim.TimReceiver; /** * Centralized UDP service dispatcher. diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 5524463fe..b76fc1e16 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; @@ -16,14 +17,13 @@ import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; import us.dot.its.jpo.ode.model.OdeTimMetadata; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.uper.UperUtil; import us.dot.its.jpo.ode.util.JsonUtils; public class TimReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(TimReceiver.class); - + private StringPublisher timPublisher; @Autowired diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java index 23b1d48fa..b8553649f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java @@ -5,18 +5,14 @@ package us.dot.its.jpo.ode.traveler; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.BeforeAll; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; public class TimIngestWatcherTest { @Test public void testRun() { - TimIngestWatcher watcher = new TimIngestWatcher(); + TimIngestWatcher watcher = new TimIngestWatcher(0); watcher.run(); // we can't easily test that the run method wrote the correct log message, but we can test that it reset the total messages received after running From 81db63ec4fb0e58cbbfa5e1231efb3ce772af00f Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 10 Oct 2024 16:25:25 -0600 Subject: [PATCH 010/264] use primitive long instead of Integer for ingest count for larger upper bound --- .../java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java | 4 ++-- .../java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java | 2 +- .../dot/its/jpo/ode/traveler/TimDepositControllerTest.java | 4 ++-- .../us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java | 6 +++--- .../us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java index d129cece4..940e200d1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java @@ -2,7 +2,7 @@ public class TimIngestTracker { - private Integer totalMessagesReceived; + private long totalMessagesReceived; private TimIngestTracker() { totalMessagesReceived = 0; @@ -16,7 +16,7 @@ private static class TimIngestMonitorHolder { private static final TimIngestTracker INSTANCE = new TimIngestTracker(); } - public Integer getTotalMessagesReceived() { + public long getTotalMessagesReceived() { return totalMessagesReceived; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java index d9270fcb9..5de3fa94f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java @@ -15,7 +15,7 @@ public TimIngestWatcher(long interval) { @Override public void run() { TimIngestTracker tracker = TimIngestTracker.getInstance(); - Integer ingested = tracker.getTotalMessagesReceived(); + long ingested = tracker.getTotalMessagesReceived(); if (ingested == 0) { logger.warn("ODE has not received TIM deposits in {} seconds.", interval); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 5cecdb3d7..744b0a3fd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -170,10 +170,10 @@ public void testDepositingTimWithExtraProperties(@Capturing TimTransmogrifier ca @Test public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; - Integer priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); + long priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived().intValue()); + assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived()); } @Test diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java index c88b900b4..1fd944ac5 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java @@ -9,9 +9,9 @@ public class TimIngestTrackerTest { @Test public void testCanIncrementTotalMessagesReceived() { TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); - assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); testTimIngestTracker.incrementTotalMessagesReceived(); - assertEquals(1, testTimIngestTracker.getTotalMessagesReceived().intValue()); + assertEquals(1, testTimIngestTracker.getTotalMessagesReceived()); } @Test @@ -20,6 +20,6 @@ public void testCanResetTotalMessagesReceived() { testTimIngestTracker.incrementTotalMessagesReceived(); assertTrue(testTimIngestTracker.getTotalMessagesReceived()> 0); testTimIngestTracker.resetTotalMessagesReceived(); - assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java index b8553649f..b87d74b3d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java @@ -17,7 +17,7 @@ public void testRun() { // we can't easily test that the run method wrote the correct log message, but we can test that it reset the total messages received after running TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); - assertEquals(0, testTimIngestTracker.getTotalMessagesReceived().intValue()); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); } } \ No newline at end of file From 785e1bc58c2f0fcfa7180c21a7dfa58a1e9d9d66 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 10 Oct 2024 16:42:13 -0600 Subject: [PATCH 011/264] Added entry to submodule compatibility guide for version 3.0.0 of the ODE --- docs/compatibility.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/compatibility.md b/docs/compatibility.md index 451264e6e..8ba92d86a 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -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) | | ----------------- | --- | --- | --- | ---- | --- | ----------- | -------- | ----------- | ----------- | +| 3.0.0 | 2.2.0 | 1.4.0 | 1.5.0 | 1.8.0 | 1.6.0 | 1.4.2 | 1.4.2 | 1.4.1 | 1.4.0 | | 2.1.0 | 2.1.0 | 1.3.0 | 1.4.0 | 1.7.0 | 1.5.0 | 1.3.0 | 1.3.0 | 1.3.0 | 1.3.0 | | 2.0.x | 2.0.0 | 1.3.0 | 1.4.0 | 1.6.0 | 1.4.0 | 1.2.0 | 1.2.0 | 1.2.0 | 1.2.0 | | 1.5.1 | 1.5.0 | 1.2.0 | 1.3.0 | 1.5.0 | 1.3.0 | 1.1.0 | 1.1.0 | 1.1.0 | 1.1.0 | From ad91aeb46b4f76922bf6ecbd703a8618dac128e6 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 10 Oct 2024 16:52:08 -0600 Subject: [PATCH 012/264] make testCanIncrementTotalMessagesReceived dynamic and not flaky --- .../us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java index 1fd944ac5..f9ae23735 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java @@ -9,9 +9,9 @@ public class TimIngestTrackerTest { @Test public void testCanIncrementTotalMessagesReceived() { TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); - assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); + long priorCount = testTimIngestTracker.getTotalMessagesReceived(); testTimIngestTracker.incrementTotalMessagesReceived(); - assertEquals(1, testTimIngestTracker.getTotalMessagesReceived()); + assertTrue(testTimIngestTracker.getTotalMessagesReceived() > priorCount); } @Test From aa5746265be6038efb3369dae85dbbe5edd40717 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Fri, 11 Oct 2024 11:20:36 -0600 Subject: [PATCH 013/264] Remove Filtered TMC Topic deposit from Asn1DecodedDataRouter, TimDepositController --- .../jpo/ode/services/asn1/Asn1DecodedDataRouter.java | 10 ---------- .../dot/its/jpo/ode/traveler/TimDepositController.java | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index e9276b21f..f2b9c393d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -103,16 +103,6 @@ public Object process(String consumedData) { // Send all TIMs also to OdeTimJson timProducer.send(odeProperties.getKafkaTopicOdeTimJson(), getRecord().key(), odeTimData); logger.debug("Submitted to TIM Pojo topic"); - // If the TIM was generated by the TMC broadcast to the filtered TMC TIM Kafka topic - try { - String generatedBy = (new JSONObject(odeTimData)).getJSONObject("metadata") - .getString("recordGeneratedBy"); - if (generatedBy.equalsIgnoreCase("TMC_VIA_SAT") || generatedBy.equalsIgnoreCase("TMC_VIA_SNMP")) { - timProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, odeTimData); - } - } catch (Exception e) { - logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); - } } else if (messageId == J2735DSRCmsgID.SPATMessage.getMsgID()) { String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); if (recordType == RecordType.dnMsg) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 32c87e474..56dea7112 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -202,16 +202,6 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimBroadcastJson(), null, obfuscatedTimData); - // If the TIM was generated by the TMC broadcast to the filtered TMC TIM Kafka topic - try { - String generatedBy = (new JSONObject(obfuscatedTimData)).getJSONObject("metadata").getString("recordGeneratedBy"); - if (generatedBy.equalsIgnoreCase("TMC")) { - stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, obfuscatedTimData); - } - } catch (Exception e) { - logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); - } - // Now that the message gas been published to OdeBradcastTim topic, it should be // changed to J2735BroadcastTim serialId timMetadata.setSerialId(serialIdJ2735); From 227d73b7c18651bd870b613b398d88c76ebc084e Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Fri, 11 Oct 2024 11:21:28 -0600 Subject: [PATCH 014/264] Add Filtered TMC Topic deposit to Asn1EncodedDataRouter --- .../jpo/ode/services/asn1/Asn1EncodedDataRouter.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 2f78af9ba..3e17cd2e9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -18,6 +18,7 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -124,6 +125,17 @@ public Object process(String consumedData) { } } + // if the TIM was generated by the TMC upload the record to the filtered TMC TIM topic + try { + String generatedBy = consumedObj.getJSONObject("metadata").getString("recordGeneratedBy"); + if (generatedBy.equalsIgnoreCase("TMC")) { + String obfuscatedDataString = consumedObj.toString().replaceAll("\"rsuPassword\": *\".*?\"", "\"rsuPassword\":\"*\""); + stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, obfuscatedDataString); + } + } catch (Exception e) { + logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); + } + // Convert JSON to POJO ServiceRequest servicerequest = getServicerequest(consumedObj); From 0b33cae6ac181dd4ba5fc6fa5d399136495dcfee Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Fri, 11 Oct 2024 14:11:32 -0600 Subject: [PATCH 015/264] Updates to README, Makefile, and devcontainer to improve onboarding and developer experience (#105) * README additions and trivial markdown format corrections * replace outdated ifconfig command with ip command in sample.env * Add .PHONY entries to Makefile since tasks don't reference local files * add makefile-tools to dev container extensions * add ignore = all to submodules to simplify local development and commit process * correct links in README and correct linter warnings where sensible and easy * clarify .env file setup steps * Revert "add makefile-tools to dev container extensions" This reverts commit 29f3e64dac58d79ea97eb7bc1fa0b3627416051c. * Revert "add ignore = all to submodules to simplify local development and commit process" This reverts commit 788f38cc6f7ac9ccc7082c932946819d1e9bb3b7. * add ignore = all to submodules to prevent commits w/ changes to submodules * add python3 support to dev container * Revert "correct links in README and correct linter warnings where sensible and easy" This reverts commit 081e9dbaa7bd84093f3c634cb12843bae16ec449. * correct link to Contributing Guide in pr template * adjust README internal links to markdown syntax for local functionality * Revert "add ignore = all to submodules to prevent commits w/ changes to submodules" This reverts commit 15a7e44710533e2c9e96f1288ef8161e42eaf235. --- .devcontainer/Dockerfile | 5 +- .devcontainer/devcontainer.json | 3 +- Makefile | 5 ++ README.md | 123 +++++++++++++++++++------------- docs/pull_request_template.md | 2 +- sample.env | 2 +- 6 files changed, 88 insertions(+), 52 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e5b121f1b..7c0fb875b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -74,4 +74,7 @@ RUN apt-get install -y g++ cmake libsasl2-dev libsasl2-modules libssl-dev librdk RUN apt install -y autoconf libtool ENV REDACTION_PROPERTIES_PATH /workspaces/jpo-ode/jpo-cvdp/config/fieldsToRedact.txt -ENV RPM_DEBUG true \ No newline at end of file +ENV RPM_DEBUG true + +# Python3 +RUN apt-get install -y python3 python3-venv python3-pip \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 078e5fb88..79fd809d6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,7 +24,8 @@ "redhat.java", "redhat.vscode-commons", "ms-vscode.cpptools", - "ms-vscode.cmake-tools" + "ms-vscode.cmake-tools", + "ms-python.python" ] } }, diff --git a/Makefile b/Makefile index 9ce27b456..f112acb0a 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,7 @@ default: $(info `make rebuild` to stop, delete, and then rebuild the containers) $(info `make clean-build` to rebuild the containers without using the cache) +.PHONY: start start: ifeq ("$(wildcard .env)", "") $(error "ERROR: jpo-ode Environment file `.env` not found in ${PWD}") @@ -25,14 +26,18 @@ ifeq ("$(wildcard ./jpo-utils/.env)", "") endif docker compose build +.PHONY: stop stop: docker compose down +.PHONY: delete delete: docker compose down -v +.PHONY: rebuild rebuild: $(MAKE) stop delete build start +.PHONY: clean-build clean-build: docker compose build --no-cache \ No newline at end of file diff --git a/README.md b/README.md index 765981547..a53071c19 100644 --- a/README.md +++ b/README.md @@ -30,22 +30,22 @@ All stakeholders are invited to provide input to these documents. To provide fee The current version and release history of the JPO-ODE: [ODE Release Notes]() -**Table of Contents** - -1. [Usage Example](#usage-example) -1. [Configuration](#configuration) -1. [Installation](#installation) -1. [File Manifest](#file-manifest) -1. [Development Setup](#development-setup) -1. [Release History](#release-history) -1. [Contact Information](#contact-information) -1. [Contributing](#contributing) -1. [Credits and Acknowledgement](#credits-and-acknowledgement) -1. [Code.gov Registration Info](#codegov-registration-info) -1. [Kubernetes](#kubernetes) -1. [Sonar Cloud](#sonar-token-configuration) ([Documentation](https://sonarcloud.io/documentation/user-guide/user-token/)) -1. [SNMP](#snmp) -1. [GitHub Artifact Usage](#githhub-artifact-usage) +## Table of Contents + +1. [Usage Example](#1-usage-example) +1. [Configuration](#2-configuration) +1. [Installation](#3-installation) +1. [File Manifest](#4-file-manifest) +1. [Development Setup](#5-development-setup) +1. [Release History](#6-release-history) +1. [Contact Information](#7-contact-information) +1. [Contributing](#8-contributing) +1. [Credits and Acknowledgement](#9-credits-and-acknowledgement) +1. [Code.gov Registration Info](#10-codegov-registration-info) +1. [Kubernetes](#11-kubernetes) +1. [Sonar Cloud](#12-sonar-token-configuration) ([Documentation](https://sonarcloud.io/documentation/user-guide/user-token/)) +1. [SNMP](#13-snmp) +1. [GitHub Artifact Usage](#14-gitHub-artifact-usage) SuWis)_%wS0geR)(nzfZnh2)S@9e2L&P$ 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

j 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

h|cB1NJYt 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 Date: Wed, 23 Oct 2024 13:59:09 -0600 Subject: [PATCH 031/264] remove duplicate java extension from .devcontainer --- .devcontainer/devcontainer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2f10f264d..97c0f0f09 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -26,7 +26,6 @@ "ms-vscode.cpptools", "ms-vscode.cmake-tools", "ms-vscode.makefile-tools", - "Oracle.oracle-java", "ms-python.python" ] } From ba5b641336c744ffe6160dcfa14522bdad078285 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 23 Oct 2024 14:03:04 -0600 Subject: [PATCH 032/264] protect against non-numerical input for monitoring interval and set sane default in catch block --- .../its/jpo/ode/traveler/TimDepositController.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 8afcadad0..877115bf9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -110,7 +110,7 @@ public TimDepositController(OdeProperties odeProperties) { : true; // start the TIM ingest monitoring service if enabled - Boolean timIngestMonitoringEnabled = Boolean.valueOf(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); + boolean timIngestMonitoringEnabled = Boolean.parseBoolean(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); if (timIngestMonitoringEnabled) { logger.info("TIM ingest monitoring enabled."); @@ -118,13 +118,12 @@ public TimDepositController(OdeProperties odeProperties) { // 3600 seconds, or one hour, was determined to be a sane default for the monitoring interval if monitoring is enabled // but there was no interval set in the .env file String interval = odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL); - // getProperty(name, default) method will not use the default value if the value is set to an empty string, so we are using getProperty(name) - // and then checking if it is null or empty to protect against the case where the value is set to an empty string in the .env file so that we can - // use Long.valueOf() without risk of a NumberFormatException. - if (interval == null || interval.isEmpty()) { - interval = "3600"; + long monitoringInterval; + try { + monitoringInterval = Long.parseLong(interval); + } catch (NumberFormatException e) { + monitoringInterval = 3600; } - Long monitoringInterval = Long.valueOf(interval); scheduledExecutorService.scheduleAtFixedRate(new TimIngestWatcher(monitoringInterval), monitoringInterval, monitoringInterval, java.util.concurrent.TimeUnit.SECONDS); } else { From 94ca42ffa107fa3681422f384d9692da60785db7 Mon Sep 17 00:00:00 2001 From: John-Wiens Date: Wed, 23 Oct 2024 15:55:01 -0600 Subject: [PATCH 033/264] Adding Compression to Ode --- adm.properties | 4 ++-- aem.properties | 4 ++-- docker-compose.yml | 3 ++- .../java/us/dot/its/jpo/ode/wrapper/MessageProducer.java | 9 +++++++++ .../dot/its/jpo/ode/SerializableMessageProducerPool.java | 1 + ppm.properties | 4 ++-- sample.env | 1 + 7 files changed, 19 insertions(+), 7 deletions(-) diff --git a/adm.properties b/adm.properties index 5e6f05536..a6a0075a0 100644 --- a/adm.properties +++ b/adm.properties @@ -22,6 +22,6 @@ asn1.j2735.kafka.partition=0 # The host ip address for the Broker. # metadata.broker.list=localhost:9092 -# specify the compression codec for all data generated: none, gzip, snappy, lz4 -compression.type=none +# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd +compression.type=zstd diff --git a/aem.properties b/aem.properties index c20211199..ce1fc0969 100644 --- a/aem.properties +++ b/aem.properties @@ -22,6 +22,6 @@ asn1.j2735.kafka.partition=0 # The host ip address for the Broker. # metadata.broker.list=localhost:9092 -# specify the compression codec for all data generated: none, gzip, snappy, lz4 -compression.type=none +# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd +compression.type=zstd diff --git a/docker-compose.yml b/docker-compose.yml index e5f5e809a..a99da126d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -41,6 +41,7 @@ services: DATA_SIGNING_ENABLED_RSU: ${DATA_SIGNING_ENABLED_RSU} DATA_SIGNING_ENABLED_SDW: ${DATA_SIGNING_ENABLED_SDW} DEFAULT_SNMP_PROTOCOL: ${DEFAULT_SNMP_PROTOCOL} + KAFKA_LINGER_MS: ${KAFKA_LINGER_MS} depends_on: kafka: condition: service_healthy @@ -245,4 +246,4 @@ services: logging: options: max-size: "10m" - max-file: "5" \ No newline at end of file + max-file: "5" diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index 2b81a2a2e..392259336 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -41,6 +41,7 @@ public class MessageProducer { public static final int DEFAULT_PRODUCER_BATCH_SIZE_BYTES = 16384; public static final int DEFAULT_PRODUCER_RETRIES = 0; public static final String DEFAULT_PRODUCER_ACKS = "all"; + public static final String COMPRESSION_TYPE = "zstd"; private static Logger logger = LoggerFactory.getLogger(MessageProducer.class); @@ -88,6 +89,12 @@ public MessageProducer( props.put("key.serializer", SERIALIZATION_STRING_SERIALIZER); props.put("value.serializer", valueSerializerFQN); + String lingerMsEnv = System.getenv("KAFKA_LINGER_MS"); + if(lingerMsEnv != null){ + int lingerMs = Integer.parseInt(lingerMsEnv); + props.put("linger.ms", lingerMs); + } + if (partitionerClass != null) { props.put("partitioner.class", partitionerClass); } @@ -143,6 +150,8 @@ private Properties setDefaultProperties() { // available to the producer for // buffering. props.put("buffer.memory", DEFAULT_PRODUCER_BUFFER_MEMORY_BYTES); + + props.put("compression.type", COMPRESSION_TYPE); return props; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java index 12692de23..dcf4e53c1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java @@ -67,6 +67,7 @@ public SerializableMessageProducerPool init() { odeProperties.getProperty("kafka.key.serializer", MessageProducer.SERIALIZATION_STRING_SERIALIZER)); props.put("value.serializer", odeProperties.getProperty("kafka.value.serializer", MessageProducer.SERIALIZATION_BYTE_ARRAY_SERIALIZER)); + props.put("compression.type", odeProperties.getProperty("kafka.producer.compression_type", MessageProducer.COMPRESSION_TYPE)); return this; } diff --git a/ppm.properties b/ppm.properties index 522ccf343..a95735645 100644 --- a/ppm.properties +++ b/ppm.properties @@ -30,6 +30,6 @@ privacy.kafka.partition=0 # The host ip address for the Broker. metadata.broker.list=your.docker.host.ip:9092 -# specify the compression codec for all data generated: none, gzip, snappy, lz4 -compression.type=none +# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd +compression.type=zstd diff --git a/sample.env b/sample.env index 9cbb1645f..005e5dc21 100644 --- a/sample.env +++ b/sample.env @@ -65,6 +65,7 @@ DEFAULT_SNMP_PROTOCOL= # The type of Kafka broker to connect to. If set to "CONFLUENT", the broker will be Confluent Cloud. Otherwise, it will be a local Kafka broker. KAFKA_TYPE= +KAFKA_LINGER_MS=1 # Confluent Cloud API access credentials (only required if KAFKA_TYPE is set to "CONFLUENT") CONFLUENT_KEY= From 0573af3942b059cf5c640d06d27f08167bfaefa2 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Thu, 24 Oct 2024 12:28:13 -0600 Subject: [PATCH 034/264] Remove KeyedOdeTimJson topic --- .devcontainer/post-create.sh | 1 - .../us/dot/its/jpo/ode/OdeProperties.java | 9 -------- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 2 +- .../services/asn1/Asn1EncodedDataRouter.java | 22 ++++++------------- .../ode/traveler/TimDepositController.java | 15 ++----------- .../us/dot/its/jpo/ode/OdePropertiesTest.java | 4 ---- 6 files changed, 10 insertions(+), 43 deletions(-) diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh index 9dc7cee81..c9f8e5057 100644 --- a/.devcontainer/post-create.sh +++ b/.devcontainer/post-create.sh @@ -18,7 +18,6 @@ bin/kafka-topics.sh --create --topic "topic.OdeRawEncodedBSMJson" --bootstrap-se # TIM bin/kafka-topics.sh --create --topic "topic.OdeTimJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.OdeTimJsonTMCFiltered" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 -bin/kafka-topics.sh --create --topic "topic.KeyedOdeTimJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.OdeTimBroadcastJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.J2735TimBroadcastJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 bin/kafka-topics.sh --create --topic "topic.OdeTIMCertExpirationTimeJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index c53beeae5..30ebef1f2 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -118,7 +118,6 @@ public class OdeProperties implements EnvironmentAware { // TIM private String kafkaTopicOdeTimJson = "topic.OdeTimJson"; private String kafkaTopicOdeTimJsonTMCFiltered = "topic.OdeTimJsonTMCFiltered"; - private String kafkaTopicKeyedOdeTimJson = "topic.KeyedOdeTimJson"; private String kafkaTopicOdeDNMsgJson = "topic.OdeDNMsgJson"; private String kafkaTopicOdeTimRxJson = "topic.OdeTimRxJson"; private String kafkaTopicOdeTimBroadcastPojo = "topic.OdeTimBroadcastPojo"; @@ -602,14 +601,6 @@ public void setKafkaTopicOdeTimJsonTMCFiltered(String kafkaTopicOdeTimJsonTMCFil this.kafkaTopicOdeTimJsonTMCFiltered = kafkaTopicOdeTimJsonTMCFiltered; } - public String getKafkaTopicKeyedOdeTimJson() { - return kafkaTopicKeyedOdeTimJson; - } - - public void setKafkaTopicKeyedOdeTimJson(String kafkaTopicKeyedOdeTimJson) { - this.kafkaTopicKeyedOdeTimJson = kafkaTopicKeyedOdeTimJson; - } - public String getUploadLocationObuLog() { return uploadLocationObuLogLog; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index c3ebe6e3f..b2e2d9be1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -65,7 +65,7 @@ public boolean isRunning() { public Topology buildTopology() { StreamsBuilder builder = new StreamsBuilder(); - builder.table("topic.KeyedOdeTimJson", Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); + builder.table("topic.OdeTimJson", Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); return builder.build(); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 4093eaed1..ad15793fb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -201,9 +201,6 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { // Cases 1 & 2 // Sign and send to RSUs - // Deposit to filtered topic if TIM is TMC-generated - depositToFilteredTopic(metadataObj, dataObj, request); - JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); String hexEncodedTim = mfObj.getString(BYTES); @@ -241,6 +238,9 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { hexEncodedTim = signTIM(hexEncodedTim, consumedObj); } + // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated + depositToFilteredTopic(metadataObj, hexEncodedTim, request); + if (request.getSdw() != null) { // Case 2 only @@ -418,31 +418,23 @@ private String stripHeader(String encodedUnsignedTim) { return toReturn; } - private Void depositToFilteredTopic(JSONObject metadataObj, JSONObject dataObj, ServiceRequest request) { + private Void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim, ServiceRequest request) { try { String generatedBy = metadataObj.getString("recordGeneratedBy"); - String uuid = request.getUUID(); + String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); if (generatedBy.equalsIgnoreCase("TMC")) { try { - String timString = odeTimJsonTopology.query(uuid); + String timString = odeTimJsonTopology.query(streamId); if (timString != null) { // Set ASN1 data in TIM metadata JSONObject timJSON = new JSONObject(timString); JSONObject metadataJSON = timJSON.getJSONObject("metadata"); - metadataJSON.put("asn1", dataObj.getJSONObject("MessageFrame").getString("bytes")); - - // Remove TIM UUID from request - JSONObject requestJSON = metadataJSON.getJSONObject("request"); - requestJSON.put("uuid", (Object) null); - metadataJSON.put("request", requestJSON); + metadataJSON.put("asn1", hexEncodedTim); timJSON.put("metadata", metadataJSON); // Send the message w/ asn1 data to the TMC-filtered topic stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, timJSON.toString()); - - // Remove the message from the KTable - stringMsgProducer.send(odeProperties.getKafkaTopicKeyedOdeTimJson(), uuid, null); } } catch (Exception e) { logger.error("Error while updating TIM: {}", e.getMessage()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index a6616c557..2c060c20b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -203,18 +203,6 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimBroadcastJson(), null, obfuscatedTimData); - try { - String generatedBy = (new JSONObject(obfuscatedTimData)).getJSONObject("metadata").getString("recordGeneratedBy"); - if (generatedBy.equalsIgnoreCase("TMC")) { - // add UUID to TIM Metadata for later querying - String timUUID = UUID.randomUUID().toString(); - request.setUUID(timUUID); - stringMsgProducer.send(odeProperties.getKafkaTopicKeyedOdeTimJson(), timUUID, obfuscatedTimData); - } - } catch (Exception e) { - logger.error("Error while checking recordGeneratedBy field: {}", e.getMessage()); - } - // Now that the message gas been published to OdeBradcastTim topic, it should be // changed to J2735BroadcastTim serialId timMetadata.setSerialId(serialIdJ2735); @@ -264,7 +252,8 @@ public synchronized ResponseEntity depositTim(String jsonString, Request // publish Broadcast TIM to a J2735 compliant topic. stringMsgProducer.send(odeProperties.getKafkaTopicJ2735TimBroadcastJson(), null, obfuscatedj2735Tim); // publish J2735 TIM also to general un-filtered TIM topic - stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJson(), null, obfuscatedj2735Tim); + // with streamID as key + stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJson(), serialIdJ2735.getStreamId(), obfuscatedj2735Tim); serialIdOde.increment(); serialIdJ2735.increment(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index 398773322..b0f2e9cfd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -94,7 +94,6 @@ public void testSettersAndGetters() { String testKafkaTopicOdeDNMsgJson = "testKafkaTopicOdeDNMsgJson"; String testKafkaTopicOdeTimJson = "testKafkaTopicOdeTimJson"; String testKafkaTopicOdeTimJsonTMCFiltered = "testKafkaTopicOdeTimJsonTMCFiltered"; - String testKafkaTopicKeyedOdeTimJson = "testKafkaTopicKeyedOdeTimJson"; String testKafkaTopicOdeBsmDuringEventPojo = "testKafkaTopicOdeBsmDuringEventPojo"; String testKafkaTopicOdeBsmRxPojo = "testKafkaTopicOdeBsmRxPojo"; String testKafkaTopicOdeBsmTxPojo = "testKafkaTopicOdeBsmTxPojo"; @@ -140,7 +139,6 @@ public void testSettersAndGetters() { testOdeProperties.setKafkaTopicOdeDNMsgJson(testKafkaTopicOdeDNMsgJson); testOdeProperties.setKafkaTopicOdeTimJson(testKafkaTopicOdeTimJson); testOdeProperties.setKafkaTopicOdeTimJsonTMCFiltered(testKafkaTopicOdeTimJsonTMCFiltered); - testOdeProperties.setKafkaTopicKeyedOdeTimJson(testKafkaTopicKeyedOdeTimJson); testOdeProperties.setKafkaTopicOdeBsmDuringEventPojo(testKafkaTopicOdeBsmDuringEventPojo); testOdeProperties.setKafkaTopicOdeBsmRxPojo(testKafkaTopicOdeBsmRxPojo); testOdeProperties.setKafkaTopicOdeBsmTxPojo(testKafkaTopicOdeBsmTxPojo); @@ -205,8 +203,6 @@ public void testSettersAndGetters() { testOdeProperties.getKafkaTopicOdeTimJson()); assertEquals("Incorrect testKafkaTopicOdeTimJsonTMCFiltered", testKafkaTopicOdeTimJsonTMCFiltered, testOdeProperties.getKafkaTopicOdeTimJsonTMCFiltered()); - assertEquals("Incorrect testKafkaTopicOdeKeyedOdeTimJson", testKafkaTopicKeyedOdeTimJson, - testOdeProperties.getKafkaTopicKeyedOdeTimJson()); assertEquals("Incorrect testKafkaTopicOdeBsmDuringEventPojo", testKafkaTopicOdeBsmDuringEventPojo, testOdeProperties.getKafkaTopicOdeBsmDuringEventPojo()); assertEquals("Incorrect testKafkaTopicOdeBsmRxPojo", testKafkaTopicOdeBsmRxPojo, From 3678173b5bb635a8dbef10d207fdb3afe7173fa0 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Thu, 24 Oct 2024 12:29:50 -0600 Subject: [PATCH 035/264] Diagram updates --- .../tim/TIM Data Flow.drawio | 44 ++++++++---------- .../tim/TIM Data Flow.drawio.png | Bin 315206 -> 309291 bytes 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio index c132cfb61..06dffdb67 100644 --- a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio +++ b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio @@ -1,4 +1,4 @@ - + @@ -156,9 +156,6 @@ - - - @@ -317,37 +314,25 @@ - + - + - - + + - - - - - - - - - - - - - + - + - + @@ -359,11 +344,20 @@ - - + + + + + + + + + + + diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png index 10da93ec17bab757573814140474f4aba47b4cb2..7ab094559ba18e455c8bc828a550a52fab8d05df 100644 GIT binary patch delta 182817 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

()7Z*q(UvlRt{7ktet#;n3?!8>k`MGnbbyJI5OR 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 z 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 o+F*&1+0lsqU(2Tg%ikwa^i?S}D_`+F2L6+kRC Date: Thu, 24 Oct 2024 12:34:24 -0600 Subject: [PATCH 036/264] Remove ServiceRequest uuid field --- .../java/us/dot/its/jpo/ode/plugin/ServiceRequest.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java index 776e10447..e5a8d21cc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java @@ -101,15 +101,6 @@ public boolean equals(Object obj) { private SituationDataWarehouse.SDW sdw; private RSU[] rsus; private SNMP snmp; - private String uuid; - - public String getUUID() { - return uuid; - } - - public void setUUID(String timUUID) { - this.uuid= timUUID; - } public RSU[] getRsus() { return rsus; From f74e44f9b3fae6a20b0cdb09171fd74bcf89be87 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Fri, 25 Oct 2024 09:40:34 -0600 Subject: [PATCH 037/264] Extract Kafka properties from OdeProperties as a first step to breaking apart the monstrosity (#110) * Migrate kafka configuration values to ODEKafkaProperties This is the first part of the work needed to separate the OdeProperties into multpile more manageable chunks. It introduces the usage of application.yaml and @Autowired in tests to more fully utilize the Spring framework. * remove @Component annotation and accept linter errors Adding the @Component annotation to the *Receivers caused double instantiations and port binding issues * migrate from application.properties to application.yaml and introducde host-ip config val * add make restart target for easier, faster restarts that don't require a full image rebuild * add missing getHostId test for odekafkaproperties * move odekafkaproperties to kafka package * correctly declare restart target as PHONY in Makefile * move OdeKafkaPropertiesTest to correct test package * add tests to OdePropertiesTest for hostIP and remove unused imports and variables * moved hostID from OdeKafkaProperties to AppContext to keep scope of new class small and directed * correct application.yaml's disabled-topics block * correct formatting in Asn1*JSONTest.java files and fix Sonarlint errors All swaps of argument positions in the mentioned tests are to align the function calls to the defition: assert*(expected, actual). Before this swap, the call was made in the tests like assert*(actual, expected) which has the same outcome when tests *pass* but is confusing when tests do not pass because the failure output will have the actual and expected values swapped in the message. * add sprint.http.multipart config values to application.yaml * Add TODO for @mcook42 to update README.md with corrected instructions once OdeProperties refactor is completed --- Dockerfile | 2 +- Makefile | 5 + README.md | 9 +- docs/UserGuide.md | 3 +- .../dot/its/jpo/ode/context/AppContext.java | 20 + .../its/jpo/ode/context/AppContextTest.java | 22 + .../us/dot/its/jpo/ode/OdeProperties.java | 759 +----------------- .../ode/SerializableMessageProducerPool.java | 11 +- .../its/jpo/ode/coder/ByteArrayPublisher.java | 9 +- .../jpo/ode/coder/FileAsn1CodecPublisher.java | 12 +- .../its/jpo/ode/coder/MessagePublisher.java | 16 +- .../its/jpo/ode/coder/OdeDataPublisher.java | 11 +- .../its/jpo/ode/coder/OdeStringPublisher.java | 11 +- .../its/jpo/ode/coder/StringPublisher.java | 27 +- .../stream/LogFileToAsn1CodecPublisher.java | 1 - .../jpo/ode/exporter/StompStringExporter.java | 13 +- .../importer/ImporterDirectoryWatcher.java | 5 +- .../jpo/ode/importer/ImporterProcessor.java | 5 +- .../its/jpo/ode/kafka/OdeKafkaProperties.java | 25 + .../ode/services/asn1/Asn1CommandManager.java | 8 +- .../services/asn1/Asn1DecodedDataRouter.java | 40 +- .../services/asn1/Asn1EncodedDataRouter.java | 10 +- .../asn1/AsnCodecRouterServiceController.java | 22 +- .../asn1/message/Asn1DecodeBSMJSON.java | 5 +- .../asn1/message/Asn1DecodeMAPJSON.java | 5 +- .../asn1/message/Asn1DecodePSMJSON.java | 5 +- .../asn1/message/Asn1DecodeSPATJSON.java | 5 +- .../asn1/message/Asn1DecodeSRMJSON.java | 5 +- .../asn1/message/Asn1DecodeSSMJSON.java | 5 +- .../asn1/message/Asn1DecodeTIMJSON.java | 5 +- .../AsnCodecMessageServiceController.java | 32 +- .../ode/services/json/ToJsonConverter.java | 9 +- .../json/ToJsonServiceController.java | 13 +- .../ode/storage/FileSystemStorageService.java | 3 +- .../ode/traveler/TimDepositController.java | 13 +- .../ode/udp/AbstractUdpReceiverPublisher.java | 7 +- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 16 +- .../udp/controller/UdpServicesController.java | 20 +- .../jpo/ode/udp/generic/GenericReceiver.java | 17 +- .../dot/its/jpo/ode/udp/map/MapReceiver.java | 14 +- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 12 +- .../its/jpo/ode/udp/spat/SpatReceiver.java | 14 +- .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 14 +- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 14 +- .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 11 +- .../jpo/ode/upload/FileUploadController.java | 27 +- .../src/main/resources/application.properties | 61 -- .../src/main/resources/application.yaml | 15 + .../us/dot/its/jpo/ode/OdePropertiesTest.java | 40 +- .../SerializableMessageProducerPoolTest.java | 4 +- .../jpo/ode/coder/ByteArrayPublisherTest.java | 3 + .../jpo/ode/coder/OdeDataPublisherTest.java | 3 + .../jpo/ode/coder/OdeStringPublisherTest.java | 4 + .../its/jpo/ode/exporter/ExporterTest.java | 21 +- .../ode/exporter/StompStringExporterTest.java | 3 + .../ImporterDirectoryWatcherTest.java | 5 +- .../ImporterDirectoryWatcherTestOld.java | 7 +- .../jpo/ode/kafka/OdeKafkaPropertiesTest.java | 43 + .../services/asn1/Asn1CommandManagerTest.java | 7 +- .../AsnCodecRouterServiceControllerTest.java | 6 +- .../asn1/message/Asn1DecodeBSMJSONTest.java | 84 +- .../asn1/message/Asn1DecodeMAPJSONTest.java | 81 +- .../asn1/message/Asn1DecodePSMJSONTest.java | 76 +- .../asn1/message/Asn1DecodeSPATJSONTest.java | 76 +- .../asn1/message/Asn1DecodeSRMJSONTest.java | 82 +- .../asn1/message/Asn1DecodeSSMJSONTest.java | 81 +- .../asn1/message/Asn1DecodeTIMJSONTest.java | 75 +- .../AsnCodecMessageServiceControllerTest.java | 34 +- .../services/json/ToJsonConverterTest.java | 3 + .../json/ToJsonServiceControllerTest.java | 10 +- .../traveler/TimDepositControllerTest.java | 4 + .../ode/upload/FileUploadControllerTest.java | 10 +- .../src/test/resources/application.yaml | 10 + pom.xml | 6 + 74 files changed, 828 insertions(+), 1343 deletions(-) create mode 100644 jpo-ode-core/src/test/java/us/dot/its/jpo/ode/context/AppContextTest.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java delete mode 100644 jpo-ode-svcs/src/main/resources/application.properties create mode 100644 jpo-ode-svcs/src/main/resources/application.yaml create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java create mode 100644 jpo-ode-svcs/src/test/resources/application.yaml diff --git a/Dockerfile b/Dockerfile index 61a6a2e4e..097312db7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ FROM eclipse-temurin:21-jre-alpine WORKDIR /home -COPY --from=builder /home/jpo-ode-svcs/src/main/resources/application.properties /home +COPY --from=builder /home/jpo-ode-svcs/src/main/resources/application.yaml /home COPY --from=builder /home/jpo-ode-svcs/src/main/resources/logback.xml /home COPY --from=builder /home/jpo-ode-svcs/target/jpo-ode-svcs.jar /home COPY ./scripts/startup_jpoode.sh /home diff --git a/Makefile b/Makefile index f112acb0a..ffeded932 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,7 @@ default: $(info `make build` to build the ODE) $(info `make stop` to stop the ODE) $(info `make delete` to stop the ODE and remove the volumes) + $(info `make restart` to stop and then start the ODE) $(info `make rebuild` to stop, delete, and then rebuild the containers) $(info `make clean-build` to rebuild the containers without using the cache) @@ -34,6 +35,10 @@ stop: delete: docker compose down -v +.PHONY: restart +restart: + $(MAKE) stop start + .PHONY: rebuild rebuild: $(MAKE) stop delete build start diff --git a/README.md b/README.md index a53071c19..d7927a544 100644 --- a/README.md +++ b/README.md @@ -165,7 +165,10 @@ The following guide contains information about the data flow diagrams for the OD **Configuration:** -If you wish to change the application properties, such as change the location of the upload service via `ode.uploadLocation.*` properties or set the `ode.kafkaBrokers` to something other than the `$DOCKER_HOST_IP:9092`, or wish to change the log file upload folder, etc. instead of setting the environment variables, modify `jpo-ode-svcs\src\main\resources\application.properties` file as desired. +If you wish to change the application properties, such as change the location of the upload service via `ode.uploadLocation.*` +properties or set the `ode.kafkaBrokers` to something other than the `$DOCKER_HOST_IP:9092`, or wish to change the log +file upload folder, etc. instead of setting the environment variables, modify `jpo-ode-svcs\src\main\resources\application.yaml` file as desired. +To adjust the settings in your unit/integration tests, modify the `jpo-ode-svcs\src\test\resources\application.yaml` file. ODE configuration can be customized for every deployment environment using environment variables. These variables can either be set locally or using the [sample.env](sample.env) file. Instructions for how to use this file can be found [here](https://github.com/usdot-jpo-ode/jpo-ode/wiki/Using-the-.env-configuration-file). @@ -302,6 +305,7 @@ Make target options: `make build` to build the ODE `make stop` to stop the ODE `make delete` to stop the ODE and remove the volumes +`make restart` to restart the ODE `make rebuild` to stop, delete, and then rebuild the containers `make clean-build` to rebuild the containers without using the cache ``` @@ -396,7 +400,8 @@ The only requirement for deploying `asn1_codec` module on Docker is the setup of To run the ODE with PPM module, you must install and start the PPM service. PPM service communicates with other services through Kafka Topics. PPM will read from the specified "Raw BSM" topic and publish the result to the specified "Filtered Bsm" topic. These topic names are specified by the following ODE and PPM properties: - - ODE properties for communications with PPM (set in application.properties) +[//]: # ((TODO(@mcook42): Once the application.yaml file is updated with the correct properties at the end of the OdeProperties refactor effort, update the following list with the correct instructions)) + - ODE properties for communications with PPM (set in application.yaml) - ode.kafkaTopicOdeBsmJson (default = topic.OdeBsmJson) - ode.kafkaTopicFilteredOdeBsmJson (default = topic.FilteredOdeBsmJson) - PPM properties for communications with ODE (set in yourconfig.properties) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7f0669803..8929e562c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -353,10 +353,11 @@ and deploying the JPO-ODE services. #### 6.6.4 - ODE Application Properties +[//]: # ((TODO(@mcook42): Once the application.yaml file is updated with the correct properties at the end of the OdeProperties refactor effort, update the following list with the correct instructions)) JPO ODE configuration can be modified in a number of ways. 1. You can specify the configuration parameters in a file named - _application.properties_ located in the same directory from which + _application.yaml_ located in the same directory from which the application is launched. 2. You may specify properties as command line options in the form of diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/context/AppContext.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/context/AppContext.java index d41e3ab19..766b24ff4 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/context/AppContext.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/context/AppContext.java @@ -19,10 +19,13 @@ import java.net.UnknownHostException; import java.util.UUID; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; +import us.dot.its.jpo.ode.eventlog.EventLogger; +@Slf4j @Configuration public class AppContext { // CONSTANTS @@ -90,9 +93,26 @@ private void init() { } public String getHostId() { + if (this.hostId == null || this.hostId.isEmpty()) { + initializeHostId(); + } return hostId; } + private void initializeHostId() { + String hostname; + try { + hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + // Let's just use a random hostname + hostname = UUID.randomUUID().toString(); + log.error("Unknown host error: {}, using random", e); + } + this.hostId = hostname; + log.info("Host ID: {}", hostId); + EventLogger.logger.info("Initializing services on host {}", hostId); + } + public String getParam(String key) { String result = null; if (key != null) { diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/context/AppContextTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/context/AppContextTest.java new file mode 100644 index 000000000..666acde6f --- /dev/null +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/context/AppContextTest.java @@ -0,0 +1,22 @@ +package us.dot.its.jpo.ode.context; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class AppContextTest { + + @Test + void getInstance() { + assertNotNull(AppContext.getInstance()); + } + + @Test + void getHostId() { + // The hostID is specific to the machine running the test, so it will be different for each machine. + // Therefore, we can only consistently check that it is not null and not an empty string. + String hostID = AppContext.getInstance().getHostId(); + assertNotNull(hostID); + assertNotEquals("", hostID); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index 061b30700..39c65360d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -15,19 +15,14 @@ ******************************************************************************/ package us.dot.its.jpo.ode; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.UUID; import jakarta.annotation.PostConstruct; +import lombok.Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -35,18 +30,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.info.BuildProperties; import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import org.thymeleaf.util.StringUtils; -import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.eventlog.EventLogger; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.plugin.OdePlugin; -import us.dot.its.jpo.ode.util.CommonUtils; -@ConfigurationProperties("ode") -@PropertySource("classpath:application.properties") + +@Configuration +@ConfigurationProperties(prefix = "ode") +@Data public class OdeProperties implements EnvironmentAware { private static final Logger logger = LoggerFactory.getLogger(OdeProperties.class); @@ -57,15 +50,13 @@ public class OdeProperties implements EnvironmentAware { /* * General Properties */ - private String version; public static final int OUTPUT_SCHEMA_VERSION = 7; private String pluginsLocations = "plugins"; - private String kafkaBrokers = null; - private static final String DEFAULT_KAFKA_PORT = "9092"; - private String kafkaProducerType = AppContext.DEFAULT_KAFKA_PRODUCER_TYPE; + @Value("${ode.host-ip:localhost}") + private String hostIP; + private Boolean verboseJson = false; private int importProcessorBufferSize = OdePlugin.INPUT_STREAM_BUFFER_SIZE; - private String hostId; private List uploadLocations = new ArrayList<>(); /* @@ -84,7 +75,7 @@ public class OdeProperties implements EnvironmentAware { // File import properties private String uploadLocationRoot = "uploads"; - private String uploadLocationObuLogLog = "bsmlog"; + private String uploadLocationObuLog = "bsmlog"; private Integer fileWatcherPeriod = 5; // time to wait between processing inbox directory for new files /* @@ -93,17 +84,6 @@ public class OdeProperties implements EnvironmentAware { private int trustRetries = 2; // if trust handshake fails, how many times to retry private int messagesUntilTrustReestablished = 10; // renew trust session every x messages - /* - * Kafka Topics - * - */ - private String[] kafkaTopicsDisabled = { - // disable all POJO topics by default except "topic.OdeBsmPojo". Never - // "topic.OdeBsmPojo because that's the only way to get data into - // "topic.OdeBsmJson - "topic.OdeBsmRxPojo", "topic.OdeBsmTxPojo", "topic.OdeBsmDuringEventPojo", "topic.OdeTimBroadcastPojo" }; - private Set kafkaTopicsDisabledSet = new HashSet<>(); - // BSM private String kafkaTopicOdeBsmPojo = "topic.OdeBsmPojo"; private String kafkaTopicOdeBsmJson = "topic.OdeBsmJson"; @@ -170,7 +150,7 @@ public class OdeProperties implements EnvironmentAware { private int genericReceiverPort = 44990; private int genericBufferSize = 2000; -// DriverAlerts + // DriverAlerts private String kafkaTopicDriverAlertJson = "topic.OdeDriverAlertJson"; // ASN.1 CODEC @@ -199,62 +179,22 @@ public class OdeProperties implements EnvironmentAware { @PostConstruct void initialize() { - setVersion(buildProperties.getVersion()); logger.info("groupId: {}", buildProperties.getGroup()); logger.info("artifactId: {}", buildProperties.getArtifact()); - logger.info("version: {}", version); + logger.info("version: {}", buildProperties.getVersion()); OdeMsgMetadata.setStaticSchemaVersion(OUTPUT_SCHEMA_VERSION); uploadLocations.add(Paths.get(uploadLocationRoot)); - String hostname; - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - // Let's just use a random hostname - hostname = UUID.randomUUID().toString(); - logger.error("Unknown host error: {}, using random", e); - } - hostId = hostname; - logger.info("Host ID: {}", hostId); - EventLogger.logger.info("Initializing services on host {}", hostId); - - if (kafkaBrokers == null) { - - logger.warn("ode.kafkaBrokers property not defined. Will try DOCKER_HOST_IP => {}", kafkaBrokers); - - String dockerIp = CommonUtils.getEnvironmentVariable("DOCKER_HOST_IP"); - - if (dockerIp == null) { - logger.warn( - "Neither ode.kafkaBrokers ode property nor DOCKER_HOST_IP environment variable are defined. Defaulting to localhost."); - dockerIp = "localhost"; - } - kafkaBrokers = dockerIp + ":" + DEFAULT_KAFKA_PORT; - - // URI for the security services /sign endpoint - if (securitySvcsSignatureUri == null) { - securitySvcsSignatureUri = "http://" + dockerIp + ":" + securitySvcsPort + "/" - + securitySvcsSignatureEndpoint; - } + // URI for the security services /sign endpoint + if (securitySvcsSignatureUri == null) { + securitySvcsSignatureUri = "http://" + hostIP + ":" + securitySvcsPort + "/" + + securitySvcsSignatureEndpoint; } - - List asList = Arrays.asList(this.getKafkaTopicsDisabled()); - logger.info("Disabled Topics: {}", asList); - kafkaTopicsDisabledSet.addAll(asList); } - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public List getUploadLocations() { - return this.uploadLocations; + return buildProperties.getVersion(); } public String getProperty(String key) { @@ -269,673 +209,8 @@ public Object getProperty(String key, int i) { return env.getProperty(key, Integer.class, i); } - public String getHostId() { - return hostId; - } - - public String getPluginsLocations() { - return pluginsLocations; - } - - public void setPluginsLocations(String pluginsLocations) { - this.pluginsLocations = pluginsLocations; - } - - public String getKafkaBrokers() { - return kafkaBrokers; - } - - public void setKafkaBrokers(String kafkaBrokers) { - this.kafkaBrokers = kafkaBrokers; - } - - public String getKafkaProducerType() { - return kafkaProducerType; - } - - public void setKafkaProducerType(String kafkaProducerType) { - this.kafkaProducerType = kafkaProducerType; - } - - public Environment getEnv() { - return env; - } - - public void setEnv(Environment env) { - this.env = env; - } - @Override public void setEnvironment(Environment environment) { env = environment; } - - public String getUploadLocationRoot() { - return uploadLocationRoot; - } - - public int getMessagesUntilTrustReestablished() { - return messagesUntilTrustReestablished; - } - - public void setMessagesUntilTrustReestablished(int messagesUntilTrustReestablished) { - this.messagesUntilTrustReestablished = messagesUntilTrustReestablished; - } - - public String getCaCertPath() { - return caCertPath; - } - - public void setCaCertPath(String caCertPath) { - this.caCertPath = caCertPath; - } - - public String getSelfCertPath() { - return selfCertPath; - } - - public void setSelfCertPath(String selfCertPath) { - this.selfCertPath = selfCertPath; - } - - public String getSelfPrivateKeyReconstructionFilePath() { - return selfPrivateKeyReconstructionFilePath; - } - - public void setSelfPrivateKeyReconstructionFilePath(String selfPrivateKeyReconstructionFilePath) { - this.selfPrivateKeyReconstructionFilePath = selfPrivateKeyReconstructionFilePath; - } - - public String getSelfSigningPrivateKeyFilePath() { - return selfSigningPrivateKeyFilePath; - } - - public void setSelfSigningPrivateKeyFilePath(String selfSigningPrivateKeyFilePath) { - this.selfSigningPrivateKeyFilePath = selfSigningPrivateKeyFilePath; - } - - public Boolean getVerboseJson() { - return verboseJson; - } - - public void setVerboseJson(Boolean verboseJson) { - this.verboseJson = verboseJson; - } - - public int getBsmReceiverPort() { - return bsmReceiverPort; - } - - public void setBsmReceiverPort(int bsmReceiverPort) { - this.bsmReceiverPort = bsmReceiverPort; - } - - public int getBsmBufferSize() { - return bsmBufferSize; - } - - public void setBsmBufferSize(int bsmBufferSize) { - this.bsmBufferSize = bsmBufferSize; - } - - public int getTimReceiverPort() { - return timReceiverPort; - } - - public void setTimReceiverPort(int timReceiverPort) { - this.timReceiverPort = timReceiverPort; - } - - public int getTimBufferSize() { - return timBufferSize; - } - - public void setTimBufferSize(int timBufferSize) { - this.timBufferSize = timBufferSize; - } - - public int getSsmReceiverPort() { - return ssmReceiverPort; - } - - public void setSsmReceiverPort(int ssmReceiverPort) { - this.ssmReceiverPort = ssmReceiverPort; - } - - public int getSsmBufferSize() { - return ssmBufferSize; - } - - public void setSsmBufferSize(int ssmBufferSize) { - this.ssmBufferSize = ssmBufferSize; - } - - public int getSrmReceiverPort() { - return srmReceiverPort; - } - - public void setSrmReceiverPort(int srmReceiverPort) { - this.srmReceiverPort = srmReceiverPort; - } - - public int getSrmBufferSize() { - return srmBufferSize; - } - - public void setSrmBufferSize(int srmBufferSize) { - this.srmBufferSize = srmBufferSize; - } - - public int getSpatReceiverPort() { - return spatReceiverPort; - } - - public void setSpatReceiverPort(int spatReceiverPort) { - this.spatReceiverPort = spatReceiverPort; - } - - public int getSpatBufferSize() { - return spatBufferSize; - } - - public void setSpatBufferSize(int spatBufferSize) { - this.spatBufferSize = spatBufferSize; - } - - public int getMapReceiverPort() { - return mapReceiverPort; - } - - public void setMapReceiverPort(int mapReceiverPort) { - this.mapReceiverPort = mapReceiverPort; - } - - public int getMapBufferSize() { - return mapBufferSize; - } - - public void setMapBufferSize(int mapBufferSize) { - this.mapBufferSize = mapBufferSize; - } - - public int getPsmReceiverPort() { - return psmReceiverPort; - } - - public void setPsmReceiverPort(int psmReceiverPort) { - this.psmReceiverPort = psmReceiverPort; - } - - public int getPsmBufferSize() { - return psmBufferSize; - } - - public void setPsmBufferSize(int psmBufferSize) { - this.psmBufferSize = psmBufferSize; - } - - public int getGenericReceiverPort() { - return genericReceiverPort; - } - - public void setGenericReceiverPort(int genericReceiverPort) { - this.genericReceiverPort = genericReceiverPort; - } - - public int getGenericBufferSize() { - return genericBufferSize; - } - - public void setGenericBufferSize(int psmBufferSize) { - this.genericBufferSize = genericBufferSize; - } - - public void setUploadLocationRoot(String uploadLocationRoot) { - this.uploadLocationRoot = uploadLocationRoot; - } - - public int getRsuSrmSlots() { - return rsuSrmSlots; - } - - public void setRsuSrmSlots(int rsuSrmSlots) { - this.rsuSrmSlots = rsuSrmSlots; - } - - public int getTrustRetries() { - return trustRetries; - } - - public void setTrustRetries(int trustRetries) { - this.trustRetries = trustRetries; - } - - public static byte[] getJpoOdeGroupId() { - return JPO_ODE_GROUP_ID; - } - - public int getImportProcessorBufferSize() { - return importProcessorBufferSize; - } - - public void setImportProcessorBufferSize(int importProcessorBufferSize) { - this.importProcessorBufferSize = importProcessorBufferSize; - } - - public String[] getKafkaTopicsDisabled() { - return kafkaTopicsDisabled; - } - - public void setKafkaTopicsDisabled(String[] kafkaTopicsDisabled) { - this.kafkaTopicsDisabled = kafkaTopicsDisabled; - } - - public Set getKafkaTopicsDisabledSet() { - return kafkaTopicsDisabledSet; - } - - public void setKafkaTopicsDisabledSet(Set kafkaTopicsDisabledSet) { - this.kafkaTopicsDisabledSet = kafkaTopicsDisabledSet; - } - - public String getKafkaTopicFilteredOdeBsmJson() { - return kafkaTopicFilteredOdeBsmJson; - } - - public void setKafkaTopicFilteredOdeBsmJson(String kafkaTopicFilteredOdeBsmJson) { - this.kafkaTopicFilteredOdeBsmJson = kafkaTopicFilteredOdeBsmJson; - } - - public String getKafkaTopicOdeBsmPojo() { - return kafkaTopicOdeBsmPojo; - } - - public void setKafkaTopicOdeBsmPojo(String kafkaTopicOdeBsmPojo) { - this.kafkaTopicOdeBsmPojo = kafkaTopicOdeBsmPojo; - } - - public String getKafkaTopicOdeBsmJson() { - return kafkaTopicOdeBsmJson; - } - - public void setKafkaTopicOdeBsmJson(String kafkaTopicOdeBsmJson) { - this.kafkaTopicOdeBsmJson = kafkaTopicOdeBsmJson; - } - - public String getKafkaTopicAsn1DecoderInput() { - return kafkaTopicAsn1DecoderInput; - } - - public void setKafkaTopicAsn1DecoderInput(String kafkaTopicAsn1DecoderInput) { - this.kafkaTopicAsn1DecoderInput = kafkaTopicAsn1DecoderInput; - } - - public String getKafkaTopicAsn1DecoderOutput() { - return kafkaTopicAsn1DecoderOutput; - } - - public void setKafkaTopicAsn1DecoderOutput(String kafkaTopicAsn1DecoderOutput) { - this.kafkaTopicAsn1DecoderOutput = kafkaTopicAsn1DecoderOutput; - } - - public String getKafkaTopicAsn1EncoderInput() { - return kafkaTopicAsn1EncoderInput; - } - - public void setKafkaTopicAsn1EncoderInput(String kafkaTopicAsn1EncoderInput) { - this.kafkaTopicAsn1EncoderInput = kafkaTopicAsn1EncoderInput; - } - - public String getKafkaTopicAsn1EncoderOutput() { - return kafkaTopicAsn1EncoderOutput; - } - - public void setKafkaTopicAsn1EncoderOutput(String kafkaTopicAsn1EncoderOutput) { - this.kafkaTopicAsn1EncoderOutput = kafkaTopicAsn1EncoderOutput; - } - - public String getKafkaTopicOdeDNMsgJson() { - return kafkaTopicOdeDNMsgJson; - } - - public void setKafkaTopicOdeDNMsgJson(String kafkaTopicOdeDNMsgJson) { - this.kafkaTopicOdeDNMsgJson = kafkaTopicOdeDNMsgJson; - } - - public String getKafkaTopicOdeTimJson() { - return kafkaTopicOdeTimJson; - } - - public void setKafkaTopicOdeTimJson(String kafkaTopicOdeTimJson) { - this.kafkaTopicOdeTimJson = kafkaTopicOdeTimJson; - } - - public String getUploadLocationObuLog() { - return uploadLocationObuLogLog; - } - - public void setUploadLocationObuLog(String uploadLocationObuLog) { - this.uploadLocationObuLogLog = uploadLocationObuLog; - } - - public String getKafkaTopicOdeBsmDuringEventPojo() { - return kafkaTopicOdeBsmDuringEventPojo; - } - - public void setKafkaTopicOdeBsmDuringEventPojo(String kafkaTopicOdeBsmDuringEventPojo) { - this.kafkaTopicOdeBsmDuringEventPojo = kafkaTopicOdeBsmDuringEventPojo; - } - - public String getKafkaTopicOdeBsmRxPojo() { - return kafkaTopicOdeBsmRxPojo; - } - - public void setKafkaTopicOdeBsmRxPojo(String kafkaTopicOdeBsmRxPojo) { - this.kafkaTopicOdeBsmRxPojo = kafkaTopicOdeBsmRxPojo; - } - - public String getKafkaTopicOdeBsmTxPojo() { - return kafkaTopicOdeBsmTxPojo; - } - - public void setKafkaTopicOdeBsmTxPojo(String kafkaTopicOdeBsmTxPojo) { - this.kafkaTopicOdeBsmTxPojo = kafkaTopicOdeBsmTxPojo; - } - - public String getKafkaTopicOdeTimRxJson() { - return kafkaTopicOdeTimRxJson; - } - - public void setKafkaTopicOdeTimRxJson(String kafkaTopicOdeTimRxJson) { - this.kafkaTopicOdeTimRxJson = kafkaTopicOdeTimRxJson; - } - - public String getKafkaTopicOdeTimBroadcastPojo() { - return kafkaTopicOdeTimBroadcastPojo; - } - - public void setKafkaTopicOdeTimBroadcastPojo(String kafkaTopicOdeTimBroadcastPojo) { - this.kafkaTopicOdeTimBroadcastPojo = kafkaTopicOdeTimBroadcastPojo; - } - - public String getKafkaTopicOdeTimBroadcastJson() { - return kafkaTopicOdeTimBroadcastJson; - } - - public void setKafkaTopicOdeTimBroadcastJson(String kafkaTopicOdeTimBroadcastJson) { - this.kafkaTopicOdeTimBroadcastJson = kafkaTopicOdeTimBroadcastJson; - } - - public String getKafkaTopicJ2735TimBroadcastJson() { - return kafkaTopicJ2735TimBroadcastJson; - } - - public void setKafkaTopicJ2735TimBroadcastJson(String kafkaTopicJ2735TimBroadcastJson) { - this.kafkaTopicJ2735TimBroadcastJson = kafkaTopicJ2735TimBroadcastJson; - } - - public String getKafkaTopicFilteredOdeTimJson() { - return kafkaTopicFilteredOdeTimJson; - } - - public void setKafkaTopicFilteredOdeTimJson(String kafkaTopicFilteredOdeTimJson) { - this.kafkaTopicFilteredOdeTimJson = kafkaTopicFilteredOdeTimJson; - } - - public String getKafkaTopicDriverAlertJson() { - return kafkaTopicDriverAlertJson; - } - - public void setKafkaTopicDriverAlertJson(String kafkaTopicDriverAlertJson) { - this.kafkaTopicDriverAlertJson = kafkaTopicDriverAlertJson; - } - - public Integer getFileWatcherPeriod() { - return fileWatcherPeriod; - } - - public void setFileWatcherPeriod(Integer fileWatcherPeriod) { - this.fileWatcherPeriod = fileWatcherPeriod; - } - - public String getSecuritySvcsSignatureUri() { - return securitySvcsSignatureUri; - } - - public void setSecuritySvcsSignatureUri(String securitySvcsSignatureUri) { - this.securitySvcsSignatureUri = securitySvcsSignatureUri; - } - - public String getRsuUsername() { - return rsuUsername; - } - - public void setRsuUsername(String rsuUsername) { - this.rsuUsername = rsuUsername; - } - - public String getRsuPassword() { - return rsuPassword; - } - - public void setRsuPassword(String rsuPassword) { - this.rsuPassword = rsuPassword; - } - - public String getKafkaTopicSdwDepositorInput() { - return kafkaTopicSdwDepositorInput; - } - - public void setKafkaTopicSdwDepositorInput(String kafkaTopicSdwDepositorInput) { - this.kafkaTopicSdwDepositorInput = kafkaTopicSdwDepositorInput; - } - - public String getKafkaTopicSignedOdeTimJsonExpiration() { - return kafkaTopicSignedOdeTimJsonExpiration; - } - public void setKafkaTopicSignedOdeTimJsonExpiration(String kafkaTopicSignedOdeTimJsonExpiration) { - this.kafkaTopicSignedOdeTimJsonExpiration = kafkaTopicSignedOdeTimJsonExpiration; - } - - public String getKafkaTopicOdeSpatTxPojo() { - return kafkaTopicOdeSpatTxPojo; - } - - - public void setKafkaTopicOdeSpatTxPojo(String kafkaTopicOdeSpatTxPojo) { - this.kafkaTopicOdeSpatTxPojo = kafkaTopicOdeSpatTxPojo; - } - - - public String getKafkaTopicOdeSpatPojo() { - return kafkaTopicOdeSpatPojo; - } - - - public void setKafkaTopicOdeSpatPojo(String kafkaTopicOdeSpatPojo) { - this.kafkaTopicOdeSpatPojo = kafkaTopicOdeSpatPojo; - } - - - public String getKafkaTopicOdeSpatJson() { - return kafkaTopicOdeSpatJson; - } - - - public void setKafkaTopicOdeSpatJson(String kafkaTopicOdeSpatJson) { - this.kafkaTopicOdeSpatJson = kafkaTopicOdeSpatJson; - } - - - public String getKafkaTopicOdeSpatRxPojo() { - return kafkaTopicOdeSpatRxPojo; - } - - - public void setKafkaTopicOdeSpatRxPojo(String kafkaTopicOdeSpatRxPojo) { - this.kafkaTopicOdeSpatRxPojo = kafkaTopicOdeSpatRxPojo; - } - - - public String getKafkaTopicOdeSpatRxJson() { - return kafkaTopicOdeSpatRxJson; - } - - - public void setKafkaTopicOdeSpatRxJson(String kafkaTopicOdeSpatRxJson) { - this.kafkaTopicOdeSpatRxJson = kafkaTopicOdeSpatRxJson; - } - - - public String getKafkaTopicFilteredOdeSpatJson() { - return kafkaTopicFilteredOdeSpatJson; - } - - - public void setKafkaTopicFilteredOdeSpatJson(String kafkaTopicFilteredOdeSpatJson) { - this.kafkaTopicFilteredOdeSpatJson = kafkaTopicFilteredOdeSpatJson; - } - - - public String getKafkaTopicOdeRawEncodedBSMJson() { - return kafkaTopicOdeRawEncodedBSMJson; - } - - - public void setKafkaTopicOdeRawEncodedBSMJson(String kafkaTopicOdeRawEncodedBSMJson) { - this.kafkaTopicOdeRawEncodedBSMJson = kafkaTopicOdeRawEncodedBSMJson; - } - - - public String getKafkaTopicOdeRawEncodedTIMJson() { - return kafkaTopicOdeRawEncodedTIMJson; - } - - - public void setKafkaTopicOdeRawEncodedTIMJson(String kafkaTopicOdeRawEncodedTIMJson) { - this.kafkaTopicOdeRawEncodedTIMJson = kafkaTopicOdeRawEncodedTIMJson; - } - - - public String getKafkaTopicOdeRawEncodedSPATJson() { - return kafkaTopicOdeRawEncodedSPATJson; - } - - - public void setKafkaTopicOdeRawEncodedSPATJson(String kafkaTopicOdeRawEncodedSPATJson) { - this.kafkaTopicOdeRawEncodedSPATJson = kafkaTopicOdeRawEncodedSPATJson; - } - - public String getKafkaTopicOdeRawEncodedMAPJson() { - return kafkaTopicOdeRawEncodedMAPJson; - } - - public void setKafkaTopicOdeRawEncodedMAPJson(String kafkaTopicOdeRawEncodedMAPJson) { - this.kafkaTopicOdeRawEncodedMAPJson = kafkaTopicOdeRawEncodedMAPJson; - } - - - public String getKafkaTopicOdeMapTxPojo() { - return kafkaTopicOdeMapTxPojo; - } - - - public void setKafkaTopicOdeMapTxPojo(String kafkaTopicOdeMapTxPojo) { - this.kafkaTopicOdeMapTxPojo = kafkaTopicOdeMapTxPojo; - } - - - public String getKafkaTopicOdeMapJson() { - return kafkaTopicOdeMapJson; - } - - - public void setKafkaTopicOdeMapJson(String kafkaTopicOdeMapJson) { - this.kafkaTopicOdeMapJson = kafkaTopicOdeMapJson; - } - - public String getKafkaTopicOdeRawEncodedPSMJson() { - return kafkaTopicOdeRawEncodedPSMJson; - } - - public void setKafkaTopicOdeRawEncodedPSMJson(String kafkaTopicOdeRawEncodedPSMJson) { - this.kafkaTopicOdeRawEncodedPSMJson = kafkaTopicOdeRawEncodedPSMJson; - } - - - public String getKafkaTopicOdePsmTxPojo() { - return kafkaTopicOdePsmTxPojo; - } - - - public void setKafkaTopicOdePsmTxPojo(String kafkaTopicOdePsmTxPojo) { - this.kafkaTopicOdePsmTxPojo = kafkaTopicOdePsmTxPojo; - } - - - public String getKafkaTopicOdePsmJson() { - return kafkaTopicOdePsmJson; - } - - - public void setKafkaTopicOdePsmJson(String kafkaTopicOdePsmJson) { - this.kafkaTopicOdePsmJson = kafkaTopicOdePsmJson; - } - - public String getKafkaTopicOdeRawEncodedSSMJson() { - return kafkaTopicOdeRawEncodedSSMJson; - } - - public void setKafkaTopicOdeRawEncodedSSMJson(String kafkaTopicOdeRawEncodedSSMJson) { - this.kafkaTopicOdeRawEncodedSSMJson = kafkaTopicOdeRawEncodedSSMJson; - } - - - public String getKafkaTopicOdeSsmPojo() { - return kafkaTopicOdeSsmPojo; - } - - - public void setKafkaTopicOdeSsmPojo(String kafkaTopicOdeSsmPojo) { - this.kafkaTopicOdeSsmPojo = kafkaTopicOdeSsmPojo; - } - - - public String getKafkaTopicOdeSsmJson() { - return kafkaTopicOdeSsmJson; - } - - - public void setKafkaTopicOdeSsmJson(String kafkaTopicOdeSsmJson) { - this.kafkaTopicOdeSsmJson = kafkaTopicOdeSsmJson; - } - - public String getKafkaTopicOdeRawEncodedSRMJson() { - return kafkaTopicOdeRawEncodedSRMJson; - } - - public void setKafkaTopicOdeRawEncodedSRMJson(String kafkaTopicOdeRawEncodedSRMJson) { - this.kafkaTopicOdeRawEncodedSRMJson = kafkaTopicOdeRawEncodedSRMJson; - } - - - public String getKafkaTopicOdeSrmTxPojo() { - return kafkaTopicOdeSrmTxPojo; - } - - - public void setKafkaTopicOdeSrmTxPojo(String kafkaTopicOdeSrmTxPojo) { - this.kafkaTopicOdeSrmTxPojo = kafkaTopicOdeSrmTxPojo; - } - - - public String getKafkaTopicOdeSrmJson() { - return kafkaTopicOdeSrmJson; - } - - - public void setKafkaTopicOdeSrmJson(String kafkaTopicOdeSrmJson) { - this.kafkaTopicOdeSrmJson = kafkaTopicOdeSrmJson; - } - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java index 12692de23..21f97de1e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java @@ -17,6 +17,7 @@ import java.util.Properties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.util.SerializableObjectPool; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -25,6 +26,7 @@ public class SerializableMessageProducerPool extends SerializableObjectPoo private static final long serialVersionUID = -2293786403623236678L; transient OdeProperties odeProperties; + transient OdeKafkaProperties odeKafkaProperties; private String brokers; private String type; @@ -32,11 +34,12 @@ public class SerializableMessageProducerPool extends SerializableObjectPoo private Properties props; - public SerializableMessageProducerPool(OdeProperties odeProperties) { + public SerializableMessageProducerPool(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; - this.brokers = odeProperties.getKafkaBrokers(); - this.type = odeProperties.getKafkaProducerType(); + this.odeKafkaProperties = odeKafkaProperties; + this.brokers = odeKafkaProperties.getBrokers(); + this.type = odeKafkaProperties.getProducerType(); this.partitionerClass = odeProperties.getProperty("kafka.partitionerClass"); init(); } @@ -74,7 +77,7 @@ public SerializableMessageProducerPool init() { @Override protected MessageProducer create() { return new MessageProducer<>(brokers, type, partitionerClass, props, - odeProperties.getKafkaTopicsDisabledSet()); + odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java index 29dd242e5..9683e8334 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -26,11 +27,11 @@ public class ByteArrayPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(ByteArrayPublisher.class); protected MessageProducer bytesProducer; - public ByteArrayPublisher(OdeProperties odeProps) { - super(odeProps); + public ByteArrayPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); this.bytesProducer = MessageProducer.defaultByteArrayMessageProducer( - odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index dcd3da77d..74ccd023d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -15,16 +15,16 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import java.io.BufferedInputStream; -import java.nio.file.Path; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; - import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + +import java.io.BufferedInputStream; +import java.nio.file.Path; public class FileAsn1CodecPublisher { @@ -43,9 +43,9 @@ public FileAsn1CodecPublisherException(String string, Exception e) { private LogFileToAsn1CodecPublisher codecPublisher; @Autowired - public FileAsn1CodecPublisher(OdeProperties odeProperties) { + public FileAsn1CodecPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - StringPublisher messagePub = new StringPublisher(odeProperties); + StringPublisher messagePub = new StringPublisher(odeProperties, odeKafkaProperties); this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java index 2dbee2afd..5e47848b0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java @@ -15,23 +15,27 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; public abstract class MessagePublisher { private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Getter + protected OdeKafkaProperties odeKafkaProperties; + // TODO(Matt): remove once all kafka properties are migrated to ODEKafkaProperties and the delegates + @Getter protected OdeProperties odeProperties; - public MessagePublisher(OdeProperties odeProps) { - this.odeProperties = odeProps; - logger.info("Using Brokers: {} of Type: {}", odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType()); + public MessagePublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; + logger.info("Using Brokers: {} of Type: {}", this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType()); } - public OdeProperties getOdeProperties() { - return odeProperties; - } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java index 1cea2e251..d586f0606 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeObject; @@ -28,12 +29,12 @@ public class OdeDataPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer objectProducer; - public OdeDataPublisher(OdeProperties odeProps, String serializer) { - super(odeProps); - this.objectProducer = new MessageProducer<>(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), + public OdeDataPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, String serializer) { + super(odeProperties, odeKafkaProperties); + this.objectProducer = new MessageProducer<>(this.odeKafkaProperties.getBrokers(), + this.odeKafkaProperties.getProducerType(), null, serializer, - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getDisabledTopics()); } public void publish(OdeData msg, String topic) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java index 612c8f3a5..11362a08e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -27,12 +28,12 @@ public class OdeStringPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer stringProducer; - public OdeStringPublisher(OdeProperties odeProps) { - super(odeProps); + public OdeStringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); this.stringProducer = MessageProducer.defaultStringMessageProducer( - odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getBrokers(), + this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java index d91142775..089d829aa 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java @@ -17,26 +17,25 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; public class StringPublisher extends MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(StringPublisher.class); - protected MessageProducer stringProducer; - - public StringPublisher(OdeProperties odeProps) { - super(odeProps); - this.stringProducer = MessageProducer.defaultStringMessageProducer( - odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + private static final Logger logger = LoggerFactory.getLogger(StringPublisher.class); + protected MessageProducer stringProducer; - } + public StringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); + this.stringProducer = MessageProducer.defaultStringMessageProducer( + this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); - public void publish(String msg, String topic) { - logger.debug("Publishing String data to {}", topic); - stringProducer.send(topic, null, msg); - } + } + public void publish(String msg, String topic) { + logger.debug("Publishing String data to {}", topic); + stringProducer.send(topic, null, msg); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java index 9420748f2..075815da5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java @@ -18,7 +18,6 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import org.slf4j.Logger; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java index 0269fe2ec..a7fa3c011 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java @@ -16,7 +16,8 @@ package us.dot.its.jpo.ode.exporter; import org.springframework.messaging.simp.SimpMessagingTemplate; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /** @@ -24,25 +25,25 @@ */ public class StompStringExporter extends Exporter{ - private OdeProperties odeProperties; + private OdeKafkaProperties odeKafkaProperties; private SimpMessagingTemplate template; private String odeTopic; public StompStringExporter( - OdeProperties odeProperties, + OdeKafkaProperties odeKafkaProperties, String stompTopic, SimpMessagingTemplate template, String odeTopic) { super(stompTopic); - this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; this.template = template; this.odeTopic = odeTopic; } @Override protected void subscribe() { - setConsumer(MessageConsumer.defaultStringMessageConsumer(odeProperties.getKafkaBrokers(), - odeProperties.getHostId() + this.getClass().getSimpleName(), + setConsumer(MessageConsumer.defaultStringMessageConsumer(odeKafkaProperties.getBrokers(), + AppContext.getInstance().getHostId() + this.getClass().getSimpleName(), new StompStringMessageDistributor(template, getTopic()))); getConsumer().setName(this.getClass().getSimpleName()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java index 40194c430..225e8824a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; public class ImporterDirectoryWatcher implements Runnable { @@ -46,7 +47,7 @@ public enum ImporterFileType { private Integer timePeriod; - public ImporterDirectoryWatcher(OdeProperties odeProperties, Path dir, Path backupDir, Path failureDir, ImporterFileType fileType, Integer timePeriod) { + public ImporterDirectoryWatcher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, Path dir, Path backupDir, Path failureDir, ImporterFileType fileType, Integer timePeriod) { this.inbox = dir; this.backup = backupDir; this.failed = failureDir; @@ -65,7 +66,7 @@ public ImporterDirectoryWatcher(OdeProperties odeProperties, Path dir, Path back logger.error("Error creating directory: " + inbox, e); } - this.importerProcessor = new ImporterProcessor(odeProperties, fileType); + this.importerProcessor = new ImporterProcessor(odeProperties, odeKafkaProperties, fileType); executor = Executors.newScheduledThreadPool(1); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java index 647bc326e..34a00af58 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher.FileAsn1CodecPublisherException; @@ -44,8 +45,8 @@ public class ImporterProcessor { private Pattern gZipPattern = Pattern.compile("application/.*gzip"); private Pattern zipPattern = Pattern.compile("application/.*zip.*"); - public ImporterProcessor(OdeProperties odeProperties, ImporterFileType fileType) { - this.codecPublisher = new FileAsn1CodecPublisher(odeProperties); + public ImporterProcessor(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, ImporterFileType fileType) { + this.codecPublisher = new FileAsn1CodecPublisher(odeProperties, odeKafkaProperties); this.odeProperties = odeProperties; this.fileType = fileType; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java new file mode 100644 index 000000000..dcec01e11 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.Set; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka") +@Data +public class OdeKafkaProperties { + + private static final Logger logger = LoggerFactory.getLogger(OdeKafkaProperties.class); + + @Value("${ode.kafka.brokers:localhost:9092}") + private String brokers; + @Value("${ode.kafka.producer-type:sync}") + private String producerType; + @Value("${ode.kafka.disabled-topics:}") + private Set disabledTopics; +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index 1072b87e7..c4fa2a8a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; @@ -77,7 +78,7 @@ public Asn1CommandManagerException(String msg, Exception e) { private String depositTopic; private RsuDepositor rsuDepositor; - public Asn1CommandManager(OdeProperties odeProperties) { + public Asn1CommandManager(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { this.odeProperties = odeProperties; @@ -86,8 +87,9 @@ public Asn1CommandManager(OdeProperties odeProperties) { try { this.rsuDepositor = new RsuDepositor(odeProperties); this.rsuDepositor.start(); - this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); + this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); this.setDepositTopic(odeProperties.getKafkaTopicSdwDepositorInput()); } catch (Exception e) { String msg = "Error starting SDW depositor"; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index f2b9c393d..37d9e563d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -19,6 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; @@ -50,23 +51,32 @@ public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor srmProducer; private MessageProducer psmProducer; - public Asn1DecodedDataRouter(OdeProperties odeProps) { + public Asn1DecodedDataRouter(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProps; - this.bsmProducer = new MessageProducer<>(odeProps.getKafkaBrokers(), odeProps.getKafkaProducerType(), null, - OdeBsmSerializer.class.getName(), odeProperties.getKafkaTopicsDisabledSet()); - this.timProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.spatProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.mapProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.srmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.psmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); + this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + null, + OdeBsmSerializer.class.getName(), + odeKafkaProperties.getDisabledTopics()); + this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 2f78af9ba..a9716bf26 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; @@ -64,15 +65,16 @@ public Asn1EncodedDataRouterException(String string) { private boolean dataSigningEnabledRSU; private boolean dataSigningEnabledSDW; - public Asn1EncodedDataRouter(OdeProperties odeProperties) { + public Asn1EncodedDataRouter(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), this.odeProperties.getKafkaTopicsDisabledSet()); + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); - this.asn1CommandManager = new Asn1CommandManager(odeProperties); + this.asn1CommandManager = new Asn1CommandManager(odeProperties, odeKafkaProperties); this.dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index 03ba821d6..2eb86d271 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,11 +15,13 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; +import org.apache.kafka.common.serialization.Serdes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; - +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -30,10 +32,10 @@ public class AsnCodecRouterServiceController { private static final Logger logger = LoggerFactory.getLogger(AsnCodecRouterServiceController.class); - org.apache.kafka.common.serialization.Serdes bas; + Serdes bas; @Autowired - public AsnCodecRouterServiceController(OdeProperties odeProps) { + public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); logger.info("Starting {}", this.getClass().getSimpleName()); @@ -41,10 +43,10 @@ public AsnCodecRouterServiceController(OdeProperties odeProps) { // asn1_codec Decoder Routing logger.info("Routing DECODED data received ASN.1 Decoder"); - Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeProps); + Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeProps, odeKafkaProperties); MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), decoderRouter); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); asn1DecoderConsumer.setName("Asn1DecoderConsumer"); decoderRouter.start(asn1DecoderConsumer, odeProps.getKafkaTopicAsn1DecoderOutput()); @@ -52,10 +54,10 @@ public AsnCodecRouterServiceController(OdeProperties odeProps) { // asn1_codec Encoder Routing logger.info("Routing ENCODED data received ASN.1 Encoder"); - Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps); + Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps, odeKafkaProperties); MessageConsumer encoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), encoderRouter); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), encoderRouter); encoderConsumer.setName("Asn1EncoderConsumer"); encoderRouter.start(encoderConsumer, odeProps.getKafkaTopicAsn1EncoderOutput()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index 49d244cf0..eedf1fa32 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeBSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeBSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getBsmStartFlag()); + public Asn1DecodeBSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getBsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java index 61f821c91..c4df633b4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -21,8 +22,8 @@ public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeMAPJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getMapStartFlag()); + public Asn1DecodeMAPJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getMapStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index 1729348ac..25f96b310 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodePSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodePSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getPsmStartFlag()); + public Asn1DecodePSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getPsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index 33077257f..7223085eb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSPATJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSPATJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSpatStartFlag()); + public Asn1DecodeSPATJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSpatStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 5f726f892..7cd104e9f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSRMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSRMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSrmStartFlag()); + public Asn1DecodeSRMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSrmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index ae9042fa9..e02800c0c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSsmStartFlag()); + public Asn1DecodeSSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index cf612dec1..03f87f8dc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeTIMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeTIMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getTimStartFlag()); + public Asn1DecodeTIMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getTimStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java index e7954ca46..10281b734 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java @@ -3,8 +3,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -17,69 +19,69 @@ public class AsnCodecMessageServiceController { private static final Logger logger = LoggerFactory.getLogger(AsnCodecMessageServiceController.class); @Autowired - public AsnCodecMessageServiceController(OdeProperties odeProps) { + public AsnCodecMessageServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); logger.info("Starting {} ", this.getClass().getSimpleName()); // asn1_codec Decoder Routing // BSM logger.info("Send encoded BSM to ASN.1 Decoder"); - Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeProps); + Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawBSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeBSMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeBSMJSON); asn1RawBSMJSONConsumer.setName("asn1DecodeBSMJSON"); asn1DecodeBSMJSON.start(asn1RawBSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedBSMJson()); // SPAT logger.info("Send encoded SPAT to ASN.1 Decoder"); - Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeProps); + Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSPATJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSPATJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSPATJSON); asn1RawSPATJSONConsumer.setName("asn1DecodeSPATJSON"); asn1DecodeSPATJSON.start(asn1RawSPATJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSPATJson()); // SSM logger.info("Send encoded SSM to ASN.1 Decoder"); - Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeProps); + Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSSMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSSMJSON); asn1RawSSMJSONConsumer.setName("asn1DecodeSSMJSON"); asn1DecodeSSMJSON.start(asn1RawSSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSSMJson()); // SRM logger.info("Send encoded SRM to ASN.1 Decoder"); - Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeProps); + Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSRMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSRMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSRMJSON); asn1RawSRMJSONConsumer.setName("asn1DecodeSRMJSON"); asn1DecodeSRMJSON.start(asn1RawSRMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSRMJson()); // TIM logger.info("Send encoded TIM to ASN.1 Decoder"); - Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeProps); + Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawTIMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeTIMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeTIMJSON); asn1RawTIMJSONConsumer.setName("asn1DecodeTIMJSON"); asn1DecodeTIMJSON.start(asn1RawTIMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedTIMJson()); //MAP logger.info("Send encoded MAP to ASN.1 Decoder"); - Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeProps); + Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSON"); asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedMAPJson()); //PSM logger.info("Send encoded PSM to ASN.1 Decoder"); - Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeProps); + Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawPSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodePSMSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodePSMSON); asn1RawPSMJSONConsumer.setName("asn1DecodePSMJSON"); asn1DecodePSMSON.start(asn1RawPSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedPSMJson()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java index 942380d87..1f83b856c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java @@ -15,6 +15,7 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.json; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.AbstractSubPubTransformer; @@ -27,11 +28,11 @@ public class ToJsonConverter extends AbstractSubPubTransformer JSON converter launchConverter(odeProps.getKafkaTopicOdeBsmPojo(), OdeBsmDeserializer.class.getName(), - new ToJsonConverter<>(odeProps, false, odeProps.getKafkaTopicOdeBsmJson())); + new ToJsonConverter<>(odeProps, odeKafkaProperties, false, odeProps.getKafkaTopicOdeBsmJson())); } private void launchConverter(String fromTopic, String serializerFQN, ToJsonConverter jsonConverter) { logger.info("Starting JSON converter, converting records from topic {} and publishing to topic {} ", fromTopic, jsonConverter.getOutputTopic()); - MessageConsumer consumer = new MessageConsumer<>(odeProperties.getKafkaBrokers(), + MessageConsumer consumer = new MessageConsumer<>(odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), jsonConverter, serializerFQN); consumer.setName(this.getClass().getName() + fromTopic + "Consumer"); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java index 4299b0075..153d7cb70 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; @@ -42,7 +43,7 @@ public class FileSystemStorageService implements StorageService { private Path logFileLocation; @Autowired - public FileSystemStorageService(OdeProperties properties) { + public FileSystemStorageService(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties properties) { this.rootLocation = Paths.get(properties.getUploadLocationRoot()); this.logFileLocation = Paths.get(properties.getUploadLocationRoot(), diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 56dea7112..d35163aea 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -34,6 +34,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; @@ -68,6 +69,7 @@ public class TimDepositController { private static final String SUCCESS = "success"; private OdeProperties odeProperties; + private OdeKafkaProperties odeKafkaProperties; private SerialId serialIdJ2735; private SerialId serialIdOde; @@ -88,18 +90,19 @@ public TimDepositControllerException(String errMsg) { } @Autowired - public TimDepositController(OdeProperties odeProperties) { + public TimDepositController(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; this.serialIdJ2735 = new SerialId(); this.serialIdOde = new SerialId(); - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.timProducer = new MessageProducer<>(odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - null, OdeTimSerializer.class.getName(), odeProperties.getKafkaTopicsDisabledSet()); + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java index f4ed3b121..449282c72 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java @@ -39,20 +39,17 @@ public void setStopped(boolean stopped) { this.stopped = stopped; } - @Autowired - public AbstractUdpReceiverPublisher(OdeProperties odeProps, int port, int bufferSize) { + protected AbstractUdpReceiverPublisher(OdeProperties odeProps, int port, int bufferSize) { this.odeProperties = odeProps; this.port = port; this.bufferSize = bufferSize; try { - socket = new DatagramSocket(this.port); + this.socket = new DatagramSocket(this.port); logger.info("Created UDP socket bound to port {}", this.port); } catch (SocketException e) { logger.error("Error creating socket with port " + this.port, e); } } - - } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index f135593a1..fe1707a33 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -14,19 +16,17 @@ public class BsmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(BsmReceiver.class); - private StringPublisher bsmPublisher; + private final StringPublisher bsmPublisher; @Autowired - public BsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getBsmReceiverPort(), odeProps.getBsmBufferSize()); - - this.bsmPublisher = new StringPublisher(odeProps); + public BsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getBsmReceiverPort(), odeProps.getBsmBufferSize()); } - public BsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public BsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.bsmPublisher = new StringPublisher(odeProps); + this.bsmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -41,7 +41,7 @@ public void run() { do { try { logger.debug("Waiting for UDP BSM packets..."); - socket.receive(packet); + this.socket.receive(packet); if (packet.getLength() > 0) { String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index c27352a9b..b0f036e33 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -3,8 +3,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.bsm.BsmReceiver; import us.dot.its.jpo.ode.udp.generic.GenericReceiver; @@ -25,7 +27,7 @@ public class UdpServicesController { private Logger logger = LoggerFactory.getLogger(UdpServicesController.class); @Autowired - public UdpServicesController(OdeProperties odeProps) { + public UdpServicesController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); // Start the UDP receivers @@ -34,28 +36,28 @@ public UdpServicesController(OdeProperties odeProps) { logger.debug("Starting UDP receiver services..."); // BSM internal - rm.submit(new BsmReceiver(odeProps)); + rm.submit(new BsmReceiver(odeProps, odeKafkaProperties)); // TIM internal - rm.submit(new TimReceiver(odeProps)); + rm.submit(new TimReceiver(odeProps, odeKafkaProperties)); // SSM internal port - rm.submit(new SsmReceiver(odeProps)); + rm.submit(new SsmReceiver(odeProps, odeKafkaProperties)); // SRM internal port - rm.submit(new SrmReceiver(odeProps)); + rm.submit(new SrmReceiver(odeProps, odeKafkaProperties)); // SPAT internal port - rm.submit(new SpatReceiver(odeProps)); + rm.submit(new SpatReceiver(odeProps, odeKafkaProperties)); // MAP internal port - rm.submit(new MapReceiver(odeProps)); + rm.submit(new MapReceiver(odeProps, odeKafkaProperties)); // PSM internal port - rm.submit(new PsmReceiver(odeProps)); + rm.submit(new PsmReceiver(odeProps, odeKafkaProperties)); // Generic Receiver internal port - rm.submit(new GenericReceiver(odeProps)); + rm.submit(new GenericReceiver(odeProps, odeKafkaProperties)); logger.debug("UDP receiver services started."); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index 90a8042d7..2d6e7bb50 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -6,6 +6,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -16,22 +18,17 @@ public class GenericReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(GenericReceiver.class); - private StringPublisher publisher; - - + private final StringPublisher publisher; @Autowired - public GenericReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getGenericReceiverPort(), odeProps.getGenericBufferSize()); - - this.publisher = new StringPublisher(odeProps); + public GenericReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getGenericReceiverPort(), odeProps.getGenericBufferSize()); } - public GenericReceiver(OdeProperties odeProps, int port, int bufferSize) { + public GenericReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.publisher = new StringPublisher(odeProps); - + this.publisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index 53a4dcd55..bf9b4fe5d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -13,19 +15,17 @@ public class MapReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(MapReceiver.class); - private StringPublisher mapPublisher; + private final StringPublisher mapPublisher; @Autowired - public MapReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getMapReceiverPort(), odeProps.getMapBufferSize()); - - this.mapPublisher = new StringPublisher(odeProps); + public MapReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getMapReceiverPort(), odeProps.getMapBufferSize()); } - public MapReceiver(OdeProperties odeProps, int port, int bufferSize) { + public MapReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.mapPublisher = new StringPublisher(odeProps); + this.mapPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index 82bb93b41..d535b067b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -16,16 +18,14 @@ public class PsmReceiver extends AbstractUdpReceiverPublisher { private StringPublisher psmPublisher; @Autowired - public PsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getPsmReceiverPort(), odeProps.getPsmBufferSize()); - - this.psmPublisher = new StringPublisher(odeProps); + public PsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getPsmReceiverPort(), odeProps.getPsmBufferSize()); } - public PsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public PsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.psmPublisher = new StringPublisher(odeProps); + this.psmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index d67706515..cb8ed0e5a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -13,19 +15,17 @@ public class SpatReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SpatReceiver.class); - private StringPublisher spatPublisher; + private final StringPublisher spatPublisher; @Autowired - public SpatReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSpatReceiverPort(), odeProps.getSpatBufferSize()); - - this.spatPublisher = new StringPublisher(odeProps); + public SpatReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSpatReceiverPort(), odeProps.getSpatBufferSize()); } - public SpatReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SpatReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.spatPublisher = new StringPublisher(odeProps); + this.spatPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index 0c1361407..a541a080d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -13,19 +15,17 @@ public class SrmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SrmReceiver.class); - private StringPublisher srmPublisher; + private final StringPublisher srmPublisher; @Autowired - public SrmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSrmReceiverPort(), odeProps.getSrmBufferSize()); - - this.srmPublisher = new StringPublisher(odeProps); + public SrmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSrmReceiverPort(), odeProps.getSrmBufferSize()); } - public SrmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SrmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.srmPublisher = new StringPublisher(odeProps); + this.srmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index cd28f5fd0..f193fbcfd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -5,6 +5,8 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -13,19 +15,17 @@ public class SsmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SsmReceiver.class); - private StringPublisher ssmPublisher; + private final StringPublisher ssmPublisher; @Autowired - public SsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSsmReceiverPort(), odeProps.getSsmBufferSize()); - - this.ssmPublisher = new StringPublisher(odeProps); + public SsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSsmReceiverPort(), odeProps.getSsmBufferSize()); } - public SsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.ssmPublisher = new StringPublisher(odeProps); + this.ssmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index cff647a00..f971cef6f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -5,6 +5,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; @@ -16,16 +17,14 @@ public class TimReceiver extends AbstractUdpReceiverPublisher { private StringPublisher timPublisher; @Autowired - public TimReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getTimReceiverPort(), odeProps.getTimBufferSize()); - - this.timPublisher = new StringPublisher(odeProps); + public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getTimReceiverPort(), odeProps.getTimBufferSize()); } - public TimReceiver(OdeProperties odeProps, int port, int bufferSize) { + public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.timPublisher = new StringPublisher(odeProps); + this.timPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java index 7ad63c352..44c88d9a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java @@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.exporter.StompStringExporter; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; @@ -51,8 +52,8 @@ public class FileUploadController { @Autowired public FileUploadController( - StorageService storageService, OdeProperties odeProperties, - SimpMessagingTemplate template) { + StorageService storageService, OdeProperties odeProperties, + OdeKafkaProperties odeKafkaProperties, SimpMessagingTemplate template) { super(); this.storageService = storageService; @@ -67,21 +68,21 @@ public FileUploadController( logger.debug("UPLOADER - Backup directory: {}", backupPath); // Create the importers that watch folders for new/modified files - threadPool.submit(new ImporterDirectoryWatcher(odeProperties, logPath, backupPath, failurePath, ImporterFileType.LOG_FILE, odeProperties.getFileWatcherPeriod())); + threadPool.submit(new ImporterDirectoryWatcher(odeProperties, odeKafkaProperties, logPath, backupPath, failurePath, ImporterFileType.LOG_FILE, odeProperties.getFileWatcherPeriod())); // Create unfiltered exporters - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSpatJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeMapJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSrmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicDriverAlertJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimBroadcastJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeBsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSpatJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeMapJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSrmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicDriverAlertJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimBroadcastJson())); // Create filtered exporters - threadPool.submit(new StompStringExporter(odeProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeTimJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeBsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeTimJson())); } @PostMapping("/upload/{type}") diff --git a/jpo-ode-svcs/src/main/resources/application.properties b/jpo-ode-svcs/src/main/resources/application.properties deleted file mode 100644 index 4fe1e2faa..000000000 --- a/jpo-ode-svcs/src/main/resources/application.properties +++ /dev/null @@ -1,61 +0,0 @@ -#General Properties -#================== -groupId=${project.groupId} -artifactId=${project.artifactId} -version=${project.version} -#server.port = 8443 -#server.ssl.key-store = classpath:jpo_ode_keystore.jks -#server.ssl.key-store-password = keystore_pass -#server.ssl.key-password = key_pass - -spring.http.multipart.max-file-size=1MB -spring.http.multipart.max-request-size=1MB - -#ode.kafkaBrokers = localhost:9092 -#ode.verboseJson = false - -#File import properties -#ode.uploadLocation = uploads -#ode.uploadLocationBsm = bsm -#ode.uploadLocationMessageFrame = messageframe - -#USDOT Situation Data Clearinghouse (SDC) / Situational Data Exchange (SDX) Properties -#========================================================================================================================= - -#RSU Properties (note - do not include quotes) -#-------------- -#ode.rsuUsername = -#ode.rsuPassword = - -#Security Properties -#------------------- -#ode.caCertPath = path/to/CaCertFile or define env variable ${ODE_CA_CERT_PATH} -#ode.selfCertPath = path/to/selfCertFile or define env variable ${ODE_SELF_CERT_PATH} -#ode.selfPrivateKeyReconstructionFilePath = path/to/selfPrivateKeyReconstructionFile or define env variable ${ODE_SELF_PRIVATE_KEY_RECONSTRUCTION_FILE_PATH} -#ode.selfSigningPrivateKeyFilePath = path/to/selfSigningPrivateKeyFile or define env variable ${ODE_SELF_SIGNING_PRIVATE_KEY_FILE_PATH} -#ode.securitySvcsSignatureUri= // The URI for signing data using the jpo-security-svcs module. Normally doesn't need to be set because ODE will calculate it based on DOCKER_HOST_IP. If the service is deployed outside Docker, it should be set to http://host:ip/sign of the server it's running on - -#Kafka Topics -#ode.kafkaTopicsDisabled = topic.OdeBsmRxPojo topic.OdeBsmTxPojo topic.OdeBsmDuringEventPojo topic.OdeTimBroadcastPojo -#BSM -#ode.kafkaTopicOdeBsmPojo = topic.OdeBsmPojo -#ode.kafkaTopicOdeBsmJson = topic.OdeBsmJson -#ode.kafkaTopicOdeBsmRxPojo= topic.OdeBsmRxPojo -#ode.kafkaTopicOdeBsmTxPojo= topic.OdeBsmTxPojo -#ode.kafkaTopicOdeBsmDuringEventPojo= topic.OdeBsmDuringEventPojo -#ode.kafkaTopicFilteredOdeBsmJson = topic.FilteredOdeBsmJson - -#TIM -#ode.kafkaTopicOdeTimPojo = topic.OdeTimPojo -#ode.kafkaTopicOdeTimJson = topic.OdeTimJson -#ode.kafkaTopicOdeDNMsgJson= topic.OdeDNMsgJson -#ode.kafkaTopicOdeDNMsgPojo= topic.OdeDNMsgPojo -#ode.kafkaTopicOdeTimRxJson= topic.OdeTimRxJson -#ode.kafkaTopicOdeTimBroadcastPojo= topic.OdeTimBroadcastPojo -#ode.kafkaTopicOdeTimBroadcastJson= topic.OdeTimBroadcastJson - -#ASN.1 CODEC -#ode.kafkaTopicAsn1DecoderInput = topic.Asn1DecoderInput -#ode.kafkaTopicAsn1DecoderOutput = topic.Asn1DecoderOutput -#ode.kafkaTopicAsn1EncoderInput = topic.Asn1EncoderInput -#ode.kafkaTopicAsn1EncoderOutput = topic.Asn1EncoderOutput diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml new file mode 100644 index 000000000..63d2f31fc --- /dev/null +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + http: + multipart: + max-file-size: 1MB + max-request-size: 1MB +ode: + host-ip: ${DOCKER_HOST_IP} + kafka: + brokers: ${DOCKER_HOST_IP}:9092 + producer-type: sync + disabled-topics: + - "topic.OdeBsmRxPojo" + - "topic.OdeBsmTxPojo" + - "topic.OdeBsmDuringEventPojo" + - "topic.OdeTimBroadcastPojo" diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index 49fc2125c..8703cb497 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -16,12 +16,8 @@ package us.dot.its.jpo.ode; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.HashSet; -import java.util.Set; - import org.junit.jupiter.api.Test; import org.springframework.boot.info.BuildProperties; import org.springframework.core.env.Environment; @@ -32,7 +28,7 @@ import mockit.Tested; import us.dot.its.jpo.ode.util.CommonUtils; -public class OdePropertiesTest { +class OdePropertiesTest { @Tested OdeProperties testOdeProperties; @@ -45,7 +41,7 @@ public class OdePropertiesTest { CommonUtils capturingCommonUtils; @Test - public void testInit() { + void testInit() { new Expectations() { { } @@ -58,14 +54,8 @@ public void testInit() { } @Test - public void testSettersAndGetters() { - - String testDdsCasPassword = "testDdsCasPassword123456"; - String testDdsCasUrl = "testDdsCasUrl123456"; - String testDdsCasUsername = "testDdsCasUsername123456"; - String testDdsWebsocketUrl = "testDdsWebsocketUrl123456"; - String testKafkaBrokers = "testKafkaBrokers123456"; - String testKafkaProducerType = "testKafkaProducerType123456"; + void testSettersAndGetters() { + String testPluginsLocations = "testpluginsLocations123456"; String testUploadLocationObuLog = "testuploadLocationObuLog123456"; String testUploadLocationRoot = "testUploadLocationRoot123456"; @@ -80,13 +70,8 @@ public void testSettersAndGetters() { int testTrustRetries = 23; String testKafkaTopicOdeBsmPojo = "testKafkaTopicOdeBsmPojo"; String testKafkaTopicOdeBsmJson = "testKafkaTopicOdeBsmJson"; - String testVersion = "1.1.0-SNAPSHOT"; int testImportProcessorBufferSize = 83; - String[] testKafkaTopicsDisabled = new String[] { "testKafkaTopicsDisabled0" }; - Set testKafkaTopicsDisabledSet = new HashSet<>(); - testKafkaTopicsDisabledSet.add("testKafkaTopicsDisabledSet0"); - String testKafkaTopicAsn1DecoderInput = "testKafkaTopicAsn1DecoderInput"; String testKafkaTopicAsn1DecoderOutput = "testKafkaTopicAsn1DecoderOutput"; String testKafkaTopicAsn1EncoderInput = "testKafkaTopicAsn1EncoderInput"; @@ -108,10 +93,9 @@ public void testSettersAndGetters() { String testRsuUsername = "testRsuUsername"; String testRsuPassword = "testRsuPassword"; + testOdeProperties.setHostIP("test-host"); testOdeProperties.setEnv(mockEnv); testOdeProperties.setEnvironment(mockEnv); - testOdeProperties.setKafkaBrokers(testKafkaBrokers); - testOdeProperties.setKafkaProducerType(testKafkaProducerType); testOdeProperties.setPluginsLocations(testPluginsLocations); testOdeProperties.setUploadLocationObuLog(testUploadLocationObuLog); testOdeProperties.setUploadLocationRoot(testUploadLocationRoot); @@ -126,10 +110,7 @@ public void testSettersAndGetters() { testOdeProperties.setTrustRetries(testTrustRetries); testOdeProperties.setKafkaTopicOdeBsmPojo(testKafkaTopicOdeBsmPojo); testOdeProperties.setKafkaTopicOdeBsmJson(testKafkaTopicOdeBsmJson); - testOdeProperties.setVersion(testVersion); testOdeProperties.setImportProcessorBufferSize(testImportProcessorBufferSize); - testOdeProperties.setKafkaTopicsDisabled(testKafkaTopicsDisabled); - testOdeProperties.setKafkaTopicsDisabledSet(testKafkaTopicsDisabledSet); testOdeProperties.setKafkaTopicAsn1DecoderInput(testKafkaTopicAsn1DecoderInput); testOdeProperties.setKafkaTopicAsn1DecoderOutput(testKafkaTopicAsn1DecoderOutput); @@ -152,10 +133,8 @@ public void testSettersAndGetters() { testOdeProperties.setRsuUsername(testRsuUsername); testOdeProperties.setRsuPassword(testRsuPassword); + assertEquals("test-host", testOdeProperties.getHostIP()); assertEquals("Incorrect testEnv", mockEnv, testOdeProperties.getEnv()); - assertEquals("Incorrect testKafkaBrokers", testKafkaBrokers, testOdeProperties.getKafkaBrokers()); - assertEquals("Incorrect testKafkaProducerType", testKafkaProducerType, - testOdeProperties.getKafkaProducerType()); assertEquals("Incorrect testpluginsLocations", testPluginsLocations, testOdeProperties.getPluginsLocations()); assertEquals("Incorrect testUploadLocationObuLog", testUploadLocationObuLog, @@ -179,13 +158,8 @@ public void testSettersAndGetters() { testOdeProperties.getKafkaTopicOdeBsmPojo()); assertEquals("Incorrect testKafkaTopicOdeBsmJson", testKafkaTopicOdeBsmJson, testOdeProperties.getKafkaTopicOdeBsmJson()); - assertEquals("Incorrect testVersion", testVersion, testOdeProperties.getVersion()); assertEquals("Incorrect testImportProcessorBufferSize", testImportProcessorBufferSize, testOdeProperties.getImportProcessorBufferSize()); - assertEquals("Incorrect testKafkaTopicsDisabled", testKafkaTopicsDisabled[0], - testOdeProperties.getKafkaTopicsDisabled()[0]); - assertTrue("Incorrect testKafkaTopicsDisabledSet", - testOdeProperties.getKafkaTopicsDisabledSet().contains("testKafkaTopicsDisabledSet0")); assertEquals("Incorrect testKafkaTopicAsn1DecoderInput", testKafkaTopicAsn1DecoderInput, testOdeProperties.getKafkaTopicAsn1DecoderInput()); @@ -225,8 +199,6 @@ public void testSettersAndGetters() { assertEquals("Incorrect testRsuUsername", testRsuUsername, testOdeProperties.getRsuUsername()); assertEquals("Incorrect RsuPassword", testRsuPassword, testOdeProperties.getRsuPassword()); - OdeProperties.getJpoOdeGroupId(); - testOdeProperties.getHostId(); testOdeProperties.getProperty("testProperty"); testOdeProperties.getProperty("testProperty", 5); testOdeProperties.getProperty("testProperty", "testDefaultValue"); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java index 96de098f2..4a9f76bb1 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java @@ -26,7 +26,6 @@ import org.apache.kafka.clients.producer.Producer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import mockit.Expectations; import mockit.Injectable; @@ -34,6 +33,7 @@ import mockit.Tested; import mockit.Verifications; //import mockit.integration.junit4.JMockit; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; //@RunWith(JMockit.class) @@ -43,6 +43,8 @@ public class SerializableMessageProducerPoolTest { SerializableMessageProducerPool testSerializableMessageProducerPool; @Injectable OdeProperties mockOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; @BeforeEach public void setUp() { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java index 3d4d132d6..b483d67dc 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java @@ -22,6 +22,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -32,6 +33,8 @@ public class ByteArrayPublisherTest { @Injectable OdeProperties testOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String testSerializer; @Mocked byte[] mockOdeBsmData; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java index d6b297b4f..c77e1ceed 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java @@ -22,6 +22,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeData; @@ -34,6 +35,8 @@ public class OdeDataPublisherTest { @Injectable OdeProperties testOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String testSerializer; @Mocked OdeBsmData mockOdeBsmData; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java index 5723a5c0b..0fd875644 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java @@ -21,6 +21,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -33,6 +34,9 @@ public class OdeStringPublisherTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java index 0229be360..5488b8fb0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java @@ -18,22 +18,18 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; -//import mockit.integration.junit4.JMockit; import static org.junit.Assert.*; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.messaging.simp.SimpMessagingTemplate; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; -//@RunWith(JMockit.class) -public class ExporterTest { +class ExporterTest { - @Test - public void shouldRun(@Mocked OdeProperties mockOdeProperties, + void shouldRun(@Mocked OdeKafkaProperties odeKafkaProperties, @Injectable SimpMessagingTemplate mockSimpMessagingTemplate, @Mocked final MessageConsumer mockByteArrayConsumer, @Mocked final MessageConsumer mockStringConsumer) { @@ -42,10 +38,7 @@ public void shouldRun(@Mocked OdeProperties mockOdeProperties, new Expectations() { { - mockOdeProperties.getKafkaBrokers(); - result = anyString; - - mockOdeProperties.getHostId(); + odeKafkaProperties.getBrokers(); result = anyString; mockStringConsumer.close(); @@ -53,9 +46,9 @@ public void shouldRun(@Mocked OdeProperties mockOdeProperties, }; try { - Exporter odeBsmExporter = new StompStringExporter( - mockOdeProperties, testTopic, mockSimpMessagingTemplate, - "odeTopic"); + Exporter odeBsmExporter = new StompStringExporter(odeKafkaProperties, + testTopic, + mockSimpMessagingTemplate, "odeTopic"); odeBsmExporter.setConsumer(mockStringConsumer); odeBsmExporter.run(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java index ac892bd65..1046052ba 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java @@ -18,6 +18,7 @@ import mockit.*; import org.junit.jupiter.api.Test; import org.springframework.messaging.simp.SimpMessagingTemplate; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; @@ -30,6 +31,8 @@ public class StompStringExporterTest { @Injectable OdeProperties injectableOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String stompTopic = "testTopic"; @Injectable SimpMessagingTemplate simpMessagingTemplate; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java index 02bd8bfe5..35b3df2b4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java @@ -28,6 +28,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; @@ -39,6 +40,8 @@ public class ImporterDirectoryWatcherTest { @Injectable OdeProperties injectableOdeProperties; @Injectable + OdeKafkaProperties odeKafkaProperties; + @Injectable Path inbox; @Injectable Path failureDir; @@ -87,7 +90,7 @@ public void testRun() throws InterruptedException, IOException { mockScheduledExecutorService.awaitTermination(anyLong, TimeUnit.SECONDS); } }; - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, backupDir, failureDir, backupDir, injectableImporterFileType, timePeriod); + testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, backupDir, failureDir, backupDir, injectableImporterFileType, timePeriod); testImporterDirectoryWatcher.run(); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java index 32e43b921..69f984fb2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java @@ -35,6 +35,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; @@ -45,6 +46,8 @@ public class ImporterDirectoryWatcherTestOld { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties odeKafkaProperties; @Mocked Path mockDir; @Injectable @@ -78,7 +81,7 @@ public void createTestObject() { } catch (IOException e) { fail("Unexpected exception in expectations block: " + e); } - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); + testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); testImporterDirectoryWatcher.setWatching(false); } @@ -94,7 +97,7 @@ public void testConstructorOdeUtilsException() { } catch (IOException e) { fail("Unexpected exception in expectations block: " + e); } - new ImporterDirectoryWatcher(injectableOdeProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); + new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); } @Test diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java new file mode 100644 index 000000000..1f23358ba --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class OdeKafkaPropertiesTest { + + @Autowired + private OdeKafkaProperties odeKafkaProperties; + + @Test + void testGetBrokers() { + assertEquals("localhost:9092", odeKafkaProperties.getBrokers()); + } + + @Test + void testGetProducerType() { + assertEquals("sync", odeKafkaProperties.getProducerType()); + } + + @Test + void testGetKafkaTopicsDisabled() { + Set kafkaTopicsDisabled = odeKafkaProperties.getDisabledTopics(); + assertEquals(4, kafkaTopicsDisabled.size()); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmRxPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmTxPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmDuringEventPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeTimBroadcastPojo")); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index 47cdb0b11..b8d8415c0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -22,14 +22,12 @@ import org.junit.jupiter.api.Test; import mockit.Capturing; -import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeTravelerInputData; -import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; -import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal.RequestVerb; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; import us.dot.its.jpo.ode.snmp.SnmpSession; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -42,6 +40,9 @@ public class Asn1CommandManagerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; @Capturing diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java index 3cad9e9e1..c4db680b7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java @@ -20,9 +20,9 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -39,6 +39,8 @@ public class AsnCodecRouterServiceControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties odeKafkaProperties; @Test @Disabled public void shouldStartTwoConsumers() { @@ -50,7 +52,7 @@ public void shouldStartTwoConsumers() { } }; - assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties)); + assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties, odeKafkaProperties)); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index af86ea450..f29edca97 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeBsmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeBSMJSONTest { - private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedBSMJson(), "topic.OdeRawEncodedBSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); - - // Validate the metadata - OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getBsmSource(), OdeBsmMetadata.BsmSource.EV); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeBSMJSONTest { + private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals(properties.getKafkaTopicOdeRawEncodedBSMJson(), "topic.OdeRawEncodedBSMJson"); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + + Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); + + // Validate the metadata + OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeBsmMetadata.BsmSource.EV, jsonMetadataObj.getBsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java index 02c6a0c7f..dda58a276 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java @@ -1,46 +1,55 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMapMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeMAPJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedMAPJson(), "topic.OdeRawEncodedMAPJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); - - // Validate the metadata - OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getMapSource(), OdeMapMetadata.MapSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeMAPJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedMAPJson", properties.getKafkaTopicOdeRawEncodedMAPJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); + + // Validate the metadata + OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeMapMetadata.MapSource.RSU, jsonMetadataObj.getMapSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index 5c7ed84f8..6dcf1ecd0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) public class Asn1DecodePSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedPSMJson(), "topic.OdeRawEncodedPSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); - - // Validate the metadata - OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getPsmSource(), OdePsmMetadata.PsmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + public void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals(properties.getKafkaTopicOdeRawEncodedPSMJson(), "topic.OdeRawEncodedPSMJson"); + } + + @Test + public void testProcess() throws XmlUtilsException, JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); + + // Validate the metadata + OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); + assertEquals(jsonMetadataObj.getPsmSource(), OdePsmMetadata.PsmSource.RSU); + assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); + assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); + assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); + assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index 47c6bb773..a9ae8c31c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSpatMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -public class Asn1DecodeSPATJSONTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSPATJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSPATJson(), "topic.OdeRawEncodedSPATJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); - - // Validate the metadata - OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSpatSource(), OdeSpatMetadata.SpatSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + + assertEquals("topic.OdeRawEncodedSPATJson", properties.getKafkaTopicOdeRawEncodedSPATJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); + + // Validate the metadata + OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSpatMetadata.SpatSource.RSU, jsonMetadataObj.getSpatSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index 3a0944d2e..ac29a8145 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSrmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeSRMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSRMJson(), "topic.OdeRawEncodedSRMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); - - // Validate the metadata - OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSrmSource(), OdeSrmMetadata.SrmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSRMJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedSRMJson", properties.getKafkaTopicOdeRawEncodedSRMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + + Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); + + // Validate the metadata + OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSrmMetadata.SrmSource.RSU, jsonMetadataObj.getSrmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 84bb81734..26a702d07 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -1,46 +1,55 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSsmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeSSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSSMJson(), "topic.OdeRawEncodedSSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); - - // Validate the metadata - OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSsmSource(), OdeSsmMetadata.SsmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSSMJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedSSMJson", properties.getKafkaTopicOdeRawEncodedSSMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); + + // Validate the metadata + OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSsmMetadata.SsmSource.RSU, jsonMetadataObj.getSsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index 4df22112f..d4f6786f3 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -1,47 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -public class Asn1DecodeTIMJSONTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeTIMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedTIMJson(), "topic.OdeRawEncodedTIMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); - - // Validate the metadata - OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getRecordGeneratedBy(), OdeMsgMetadata.GeneratedBy.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedTIMJson", properties.getKafkaTopicOdeRawEncodedTIMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); + + // Validate the metadata + OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeMsgMetadata.GeneratedBy.RSU, jsonMetadataObj.getRecordGeneratedBy()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java index 2cf131c7e..bed8866d9 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java @@ -1,19 +1,31 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + import static org.junit.Assert.assertNotNull; -import org.junit.jupiter.api.Test; +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class AsnCodecMessageServiceControllerTest { -import us.dot.its.jpo.ode.OdeProperties; - -public class AsnCodecMessageServiceControllerTest { + @Autowired + OdeKafkaProperties odeKafkaProps; + + @Test + void shouldStartTwoConsumers() { + OdeProperties odeProps = new OdeProperties(); - @Test - public void shouldStartTwoConsumers() { - OdeProperties odeProps = new OdeProperties(); - odeProps.setKafkaBrokers("localhost:9092"); - AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeProps); - assertNotNull(asnCodecMessageServiceController); - } + AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeProps, odeKafkaProps); + assertNotNull(asnCodecMessageServiceController); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java index 44d736835..1a3f905e2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java @@ -21,6 +21,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -33,6 +34,8 @@ public class ToJsonConverterTest { @Injectable OdeProperties mockOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable boolean mockVerbose; @Injectable String mockTopic; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java index b703558d3..bee54d235 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java @@ -17,9 +17,9 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; @@ -27,7 +27,9 @@ public class ToJsonServiceControllerTest { @Injectable - OdeProperties injectableOdeProperties; + OdeProperties odeProperties; + @Injectable + OdeKafkaProperties mockOdeKafkaProperties; // @Capturing // ToJsonConverter capturingToJsonConverter; @@ -38,7 +40,7 @@ public class ToJsonServiceControllerTest { public void test() { new Expectations() { { - new ToJsonConverter<>((OdeProperties) any, anyBoolean, anyString); + new ToJsonConverter<>((OdeProperties) any, (OdeKafkaProperties) any, anyBoolean, anyString); times = 1; new MessageConsumer<>(anyString, anyString, (MessageProcessor) any, anyString); @@ -46,7 +48,7 @@ public void test() { } }; - new ToJsonServiceController(injectableOdeProperties); + new ToJsonServiceController(odeProperties, mockOdeKafkaProperties); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 911a77919..e8d61a71d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -28,6 +28,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; @@ -46,6 +47,9 @@ public class TimDepositControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java index c83b30afd..1d56aca12 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java @@ -18,8 +18,6 @@ import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; -import mockit.Mock; -import mockit.MockUp; import mockit.Mocked; import org.junit.jupiter.api.BeforeEach; @@ -27,6 +25,7 @@ import org.springframework.http.HttpStatus; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.multipart.MultipartFile; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; @@ -47,6 +46,9 @@ public class FileUploadControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable SimpMessagingTemplate injectableSimpMessagingTemplate; @@ -79,8 +81,8 @@ public void constructorShouldLaunchSevenThreads() { times = 11; } }; - testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, - injectableSimpMessagingTemplate); + testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, injectableOdeKafkaProperties, + injectableSimpMessagingTemplate); } @Test diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml new file mode 100644 index 000000000..cd3de12c1 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -0,0 +1,10 @@ +ode: + host-ip: test-host + kafka: + brokers: localhost:9092 + producer-type: sync + disabled-topics: + - "topic.OdeBsmRxPojo" + - "topic.OdeBsmTxPojo" + - "topic.OdeBsmDuringEventPojo" + - "topic.OdeTimBroadcastPojo" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4463b2307..4e563673a 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,12 @@ 5.9.3 test + + org.projectlombok + lombok + 1.18.30 + annotationProcessor + From 90704f10aba88364c0cf2900505bcf56746173cc Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Fri, 25 Oct 2024 15:34:31 -0600 Subject: [PATCH 038/264] Update TIM schema to support all metadata types --- .../main/resources/schemas/schema-tim.json | 137 ++++++++++++++++-- 1 file changed, 127 insertions(+), 10 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index 4128d3ec7..533069e69 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -65,24 +65,141 @@ }, "asn1": { "type": "string" + }, + "request": { + "$ref": "#/$defs/MetadataRequest" } }, "required": [ - "securityResultCode", - "recordGeneratedBy", "schemaVersion", + "recordGeneratedBy", + "payloadType", "odePacketID", + "serialId", "sanitized", "recordGeneratedAt", - "recordType", "maxDurationTime", - "odeTimStartDateTime", - "receivedMessageDetails", - "payloadType", - "serialId", - "logFileName", - "odeReceivedAt", - "originIp" + "odeReceivedAt" + ] + }, + "MetadataRequest": { + "type": "object", + "properties": { + "ode": { + "$ref": "#/$defs/RequestOde" + }, + "rsus": { + "type": "object", + "properties": { + "rsus": { + "$ref": "#/$defs/RequestRsus" + } + }, + "required": [ + "rsus" + ] + }, + "snmp": { + "$ref": "#/$defs/RequestSnmp" + } + }, + "required": [ + "ode", + "rsus", + "snmp" + ] + }, + "RequestOde": { + "type": "object", + "properties": { + "verb": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "verb", + "version" + ] + }, + "RequestRsus": { + "type": "object", + "properties": { + "rsuTarget": { + "type": "string" + }, + "rsuUsername": { + "type": "string" + }, + "rsuPassword": { + "type": "string" + }, + "snmpProtocol": { + "type": "string" + }, + "rsuRetries": { + "type": "string" + }, + "rsuTimeout": { + "type": "string" + }, + "rsuIndex": { + "type": "string" + } + }, + "required": [ + "rsuTarget", + "rsuUsername", + "rsuPassword", + "snmpProtocol", + "rsuRetries", + "rsuTimeout", + "rsuIndex" + ] + }, + "RequestSnmp": { + "type": "object", + "properties": { + "mode": { + "type": "string" + }, + "deliverystop": { + "type": "string" + }, + "rsuid": { + "type": "string" + }, + "deliverystart": { + "type": "string" + }, + "enable": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "msgid": { + "type": "string" + }, + "interval": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": [ + "mode", + "deliverystart", + "deliverystop", + "rsuid", + "enable", + "channel", + "msgid", + "interval", + "status" ] }, "OdeRecordGeneratedBy": { From a3db8480e6bc9762c8a36bbda386b10b85b74016 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Tue, 29 Oct 2024 00:08:31 -0600 Subject: [PATCH 039/264] Includes the sdw object in the metadata.request object in the schema --- .../main/resources/schemas/schema-tim.json | 85 +++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index 533069e69..b7749be6d 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -88,6 +88,9 @@ "ode": { "$ref": "#/$defs/RequestOde" }, + "sdw": { + "$ref": "#/$defs/RequestSdw" + }, "rsus": { "type": "object", "properties": { @@ -102,12 +105,7 @@ "snmp": { "$ref": "#/$defs/RequestSnmp" } - }, - "required": [ - "ode", - "rsus", - "snmp" - ] + } }, "RequestOde": { "type": "object", @@ -124,6 +122,45 @@ "version" ] }, + "RequestSdw": { + "type": "object", + "properties": { + "serviceRegion": { + "$ref": "#/$defs/OdeGeoRegion" + }, + "ttl": { + "type": "string", + "enum": [ + "oneminute", + "thirtyminutes", + "oneday", + "oneweek", + "onemonth", + "oneyear" + ] + }, + "groupID": { + "type": "string" + }, + "deliverystart": { + "type": "string" + }, + "deliverystop": { + "type": "string" + }, + "recordId": { + "type": "string" + }, + "estimatedRemovalDate": { + "type": "string" + } + }, + "required": [ + "recordId", + "ttl", + "serviceRegion" + ] + }, "RequestRsus": { "type": "object", "properties": { @@ -202,6 +239,21 @@ "status" ] }, + "OdeGeoRegion": { + "type": "object", + "properties": { + "nwCorner": { + "$ref": "#/$defs/OdePosition3D" + }, + "seCorner": { + "$ref": "#/$defs/OdePosition3D" + } + }, + "required": [ + "nwCorner", + "seCorner" + ] + }, "OdeRecordGeneratedBy": { "type": [ "string", @@ -1090,6 +1142,27 @@ "long" ] }, + "OdePosition3D": { + "type": "object", + "properties": { + "latitude": { + "type": "string" + }, + "longitude": { + "type": "string" + }, + "elevation": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "latitude", + "longitude" + ] + }, "J2735MUTCDCode": { "oneOf": [ { From 924ad08051c0c5592a4ba7a532f20c15d86c15c7 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Wed, 30 Oct 2024 07:54:52 -0600 Subject: [PATCH 040/264] Merge branch 'develop' into 'generated-tmc-topic' --- .devcontainer/Dockerfile | 5 +- .devcontainer/devcontainer.json | 4 +- .github/workflows/artifact-publish.yml | 4 +- Dockerfile | 2 +- Makefile | 10 + README.md | 134 ++-- docker-compose.yml | 3 + docs/UserGuide.md | 3 +- docs/compatibility.md | 1 + docs/pull_request_template.md | 2 +- docs/release_process.md | 16 +- jpo-ode-core/mvnw | 0 jpo-ode-core/mvnw.cmd | 0 .../dot/its/jpo/ode/context/AppContext.java | 20 + .../main/resources/schemas/schema-map.json | 9 + .../main/resources/schemas/schema-spat.json | 27 +- .../main/resources/schemas/schema-srm.json | 14 +- .../main/resources/schemas/schema-ssm.json | 9 + .../main/resources/schemas/schema-tim.json | 14 +- .../its/jpo/ode/context/AppContextTest.java | 22 + jpo-ode-svcs/mvnw | 0 jpo-ode-svcs/mvnw.cmd | 0 jpo-ode-svcs/pom.xml | 34 + jpo-ode-svcs/run.bat | 0 jpo-ode-svcs/run.sh | 0 .../jpo/ode/ConfigEnvironmentVariables.java | 6 + .../us/dot/its/jpo/ode/OdeProperties.java | 757 +----------------- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 10 +- .../ode/SerializableMessageProducerPool.java | 11 +- .../its/jpo/ode/coder/ByteArrayPublisher.java | 9 +- .../jpo/ode/coder/FileAsn1CodecPublisher.java | 12 +- .../its/jpo/ode/coder/MessagePublisher.java | 16 +- .../its/jpo/ode/coder/OdeDataPublisher.java | 11 +- .../its/jpo/ode/coder/OdeStringPublisher.java | 11 +- .../its/jpo/ode/coder/StringPublisher.java | 27 +- .../stream/LogFileToAsn1CodecPublisher.java | 17 +- .../jpo/ode/exporter/StompStringExporter.java | 13 +- .../importer/ImporterDirectoryWatcher.java | 5 +- .../jpo/ode/importer/ImporterProcessor.java | 5 +- .../its/jpo/ode/kafka/OdeKafkaProperties.java | 25 + .../ode/services/asn1/Asn1CommandManager.java | 8 +- .../services/asn1/Asn1DecodedDataRouter.java | 40 +- .../services/asn1/Asn1EncodedDataRouter.java | 12 +- .../asn1/AsnCodecRouterServiceController.java | 22 +- .../asn1/message/Asn1DecodeBSMJSON.java | 5 +- .../asn1/message/Asn1DecodeMAPJSON.java | 5 +- .../asn1/message/Asn1DecodePSMJSON.java | 5 +- .../asn1/message/Asn1DecodeSPATJSON.java | 5 +- .../asn1/message/Asn1DecodeSRMJSON.java | 5 +- .../asn1/message/Asn1DecodeSSMJSON.java | 5 +- .../asn1/message/Asn1DecodeTIMJSON.java | 5 +- .../AsnCodecMessageServiceController.java | 32 +- .../ode/services/json/ToJsonConverter.java | 9 +- .../json/ToJsonServiceController.java | 13 +- .../ode/storage/FileSystemStorageService.java | 3 +- .../ode/traveler/TimDepositController.java | 39 +- .../jpo/ode/traveler/TimIngestTracker.java | 30 + .../jpo/ode/traveler/TimIngestWatcher.java | 29 + .../ode/udp/AbstractUdpReceiverPublisher.java | 29 +- .../us/dot/its/jpo/ode/udp/UdpHexDecoder.java | 238 ++++++ .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 75 +- .../udp/controller/UdpServicesController.java | 30 +- .../jpo/ode/udp/generic/GenericReceiver.java | 112 +++ .../dot/its/jpo/ode/udp/map/MapReceiver.java | 61 +- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 56 +- .../its/jpo/ode/udp/spat/SpatReceiver.java | 59 +- .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 59 +- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 59 +- .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 55 +- .../us/dot/its/jpo/ode/uper/UperUtil.java | 92 ++- .../jpo/ode/upload/FileUploadController.java | 27 +- .../src/main/resources/application.properties | 61 -- .../src/main/resources/application.yaml | 15 + .../us/dot/its/jpo/ode/OdePropertiesTest.java | 40 +- .../its/jpo/ode/OdeTimJsonTopologyTest.java | 19 +- .../SerializableMessageProducerPoolTest.java | 4 +- .../jpo/ode/coder/ByteArrayPublisherTest.java | 3 + .../jpo/ode/coder/OdeDataPublisherTest.java | 3 + .../jpo/ode/coder/OdeStringPublisherTest.java | 4 + .../its/jpo/ode/exporter/ExporterTest.java | 21 +- .../ode/exporter/StompStringExporterTest.java | 3 + .../ImporterDirectoryWatcherTest.java | 5 +- .../ImporterDirectoryWatcherTestOld.java | 7 +- .../jpo/ode/kafka/OdeKafkaPropertiesTest.java | 43 + .../services/asn1/Asn1CommandManagerTest.java | 7 +- .../AsnCodecRouterServiceControllerTest.java | 6 +- .../asn1/message/Asn1DecodeBSMJSONTest.java | 84 +- .../asn1/message/Asn1DecodeMAPJSONTest.java | 81 +- .../asn1/message/Asn1DecodePSMJSONTest.java | 76 +- .../asn1/message/Asn1DecodeSPATJSONTest.java | 76 +- .../asn1/message/Asn1DecodeSRMJSONTest.java | 82 +- .../asn1/message/Asn1DecodeSSMJSONTest.java | 81 +- .../asn1/message/Asn1DecodeTIMJSONTest.java | 75 +- .../AsnCodecMessageServiceControllerTest.java | 34 +- .../services/json/ToJsonConverterTest.java | 3 + .../json/ToJsonServiceControllerTest.java | 10 +- .../traveler/TimDepositControllerTest.java | 17 +- .../ode/traveler/TimIngestTrackerTest.java | 25 + .../ode/traveler/TimIngestWatcherTest.java | 18 + .../ode/upload/FileUploadControllerTest.java | 10 +- .../src/test/resources/application.yaml | 10 + pom.xml | 6 + sample.env | 10 +- scripts/tests/udpsender_generic.py | 33 + 104 files changed, 1721 insertions(+), 1743 deletions(-) mode change 100644 => 100755 jpo-ode-core/mvnw mode change 100644 => 100755 jpo-ode-core/mvnw.cmd create mode 100644 jpo-ode-core/src/test/java/us/dot/its/jpo/ode/context/AppContextTest.java mode change 100644 => 100755 jpo-ode-svcs/mvnw mode change 100644 => 100755 jpo-ode-svcs/mvnw.cmd mode change 100644 => 100755 jpo-ode-svcs/run.bat mode change 100644 => 100755 jpo-ode-svcs/run.sh create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java delete mode 100644 jpo-ode-svcs/src/main/resources/application.properties create mode 100644 jpo-ode-svcs/src/main/resources/application.yaml create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java create mode 100644 jpo-ode-svcs/src/test/resources/application.yaml create mode 100644 scripts/tests/udpsender_generic.py diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index e5b121f1b..7c0fb875b 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -74,4 +74,7 @@ RUN apt-get install -y g++ cmake libsasl2-dev libsasl2-modules libssl-dev librdk RUN apt install -y autoconf libtool ENV REDACTION_PROPERTIES_PATH /workspaces/jpo-ode/jpo-cvdp/config/fieldsToRedact.txt -ENV RPM_DEBUG true \ No newline at end of file +ENV RPM_DEBUG true + +# Python3 +RUN apt-get install -y python3 python3-venv python3-pip \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 078e5fb88..97c0f0f09 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -24,7 +24,9 @@ "redhat.java", "redhat.vscode-commons", "ms-vscode.cpptools", - "ms-vscode.cmake-tools" + "ms-vscode.cmake-tools", + "ms-vscode.makefile-tools", + "ms-python.python" ] } }, diff --git a/.github/workflows/artifact-publish.yml b/.github/workflows/artifact-publish.yml index cb4b8e259..8321ef7e0 100644 --- a/.github/workflows/artifact-publish.yml +++ b/.github/workflows/artifact-publish.yml @@ -23,9 +23,9 @@ jobs: run: mvn versions:set -DremoveSnapshot - name: Build with Maven - run: mvn -B package --file pom.xml + run: mvn -B clean package --file pom.xml -DskipTests -Ppackage-jar - name: Publish to GitHub Packages - run: mvn --batch-mode -Dgithub_organization=${{ github.repository_owner }} deploy + run: mvn --batch-mode -Dgithub_organization=${{ github.repository_owner }} deploy -DskipTests -Ppackage-jar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 61a6a2e4e..097312db7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ FROM eclipse-temurin:21-jre-alpine WORKDIR /home -COPY --from=builder /home/jpo-ode-svcs/src/main/resources/application.properties /home +COPY --from=builder /home/jpo-ode-svcs/src/main/resources/application.yaml /home COPY --from=builder /home/jpo-ode-svcs/src/main/resources/logback.xml /home COPY --from=builder /home/jpo-ode-svcs/target/jpo-ode-svcs.jar /home COPY ./scripts/startup_jpoode.sh /home diff --git a/Makefile b/Makefile index 9ce27b456..ffeded932 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,11 @@ default: $(info `make build` to build the ODE) $(info `make stop` to stop the ODE) $(info `make delete` to stop the ODE and remove the volumes) + $(info `make restart` to stop and then start the ODE) $(info `make rebuild` to stop, delete, and then rebuild the containers) $(info `make clean-build` to rebuild the containers without using the cache) +.PHONY: start start: ifeq ("$(wildcard .env)", "") $(error "ERROR: jpo-ode Environment file `.env` not found in ${PWD}") @@ -25,14 +27,22 @@ ifeq ("$(wildcard ./jpo-utils/.env)", "") endif docker compose build +.PHONY: stop stop: docker compose down +.PHONY: delete delete: docker compose down -v +.PHONY: restart +restart: + $(MAKE) stop start + +.PHONY: rebuild rebuild: $(MAKE) stop delete build start +.PHONY: clean-build clean-build: docker compose build --no-cache \ No newline at end of file diff --git a/README.md b/README.md index 765981547..17ea98a7b 100644 --- a/README.md +++ b/README.md @@ -30,22 +30,22 @@ All stakeholders are invited to provide input to these documents. To provide fee The current version and release history of the JPO-ODE: [ODE Release Notes]() -**Table of Contents** - -1. [Usage Example](#usage-example) -1. [Configuration](#configuration) -1. [Installation](#installation) -1. [File Manifest](#file-manifest) -1. [Development Setup](#development-setup) -1. [Release History](#release-history) -1. [Contact Information](#contact-information) -1. [Contributing](#contributing) -1. [Credits and Acknowledgement](#credits-and-acknowledgement) -1. [Code.gov Registration Info](#codegov-registration-info) -1. [Kubernetes](#kubernetes) -1. [Sonar Cloud](#sonar-token-configuration) ([Documentation](https://sonarcloud.io/documentation/user-guide/user-token/)) -1. [SNMP](#snmp) -1. [GitHub Artifact Usage](#githhub-artifact-usage) +## Table of Contents + +1. [Usage Example](#1-usage-example) +1. [Configuration](#2-configuration) +1. [Installation](#3-installation) +1. [File Manifest](#4-file-manifest) +1. [Development Setup](#5-development-setup) +1. [Release History](#6-release-history) +1. [Contact Information](#7-contact-information) +1. [Contributing](#8-contributing) +1. [Credits and Acknowledgement](#9-credits-and-acknowledgement) +1. [Code.gov Registration Info](#10-codegov-registration-info) +1. [Kubernetes](#11-kubernetes) +1. [Sonar Cloud](#12-sonar-token-configuration) ([Documentation](https://sonarcloud.io/documentation/user-guide/user-token/)) +1. [SNMP](#13-snmp) +1. [GitHub Artifact Usage](#14-gitHub-artifact-usage) + + + package-jar + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + lib/ + us.dot.its.jpo.ode.OdeSvcsApplication + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + repackage + none + + + + + + + diff --git a/jpo-ode-svcs/run.bat b/jpo-ode-svcs/run.bat old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/run.sh b/jpo-ode-svcs/run.sh old mode 100644 new mode 100755 diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java new file mode 100644 index 000000000..9992afeb6 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java @@ -0,0 +1,6 @@ +package us.dot.its.jpo.ode; + +public class ConfigEnvironmentVariables { + public static final String ODE_TIM_INGEST_MONITORING_ENABLED = "ODE_TIM_INGEST_MONITORING_ENABLED"; + public static final String ODE_TIM_INGEST_MONITORING_INTERVAL = "ODE_TIM_INGEST_MONITORING_INTERVAL"; // in seconds +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index 30ebef1f2..f6f1e57c6 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -15,19 +15,14 @@ ******************************************************************************/ package us.dot.its.jpo.ode; -import java.net.InetAddress; -import java.net.UnknownHostException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import java.util.UUID; import jakarta.annotation.PostConstruct; +import lombok.Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -35,18 +30,16 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.info.BuildProperties; import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import org.thymeleaf.util.StringUtils; -import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.eventlog.EventLogger; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.plugin.OdePlugin; -import us.dot.its.jpo.ode.util.CommonUtils; -@ConfigurationProperties("ode") -@PropertySource("classpath:application.properties") + +@Configuration +@ConfigurationProperties(prefix = "ode") +@Data public class OdeProperties implements EnvironmentAware { private static final Logger logger = LoggerFactory.getLogger(OdeProperties.class); @@ -57,15 +50,13 @@ public class OdeProperties implements EnvironmentAware { /* * General Properties */ - private String version; public static final int OUTPUT_SCHEMA_VERSION = 7; private String pluginsLocations = "plugins"; - private String kafkaBrokers = null; - private static final String DEFAULT_KAFKA_PORT = "9092"; - private String kafkaProducerType = AppContext.DEFAULT_KAFKA_PRODUCER_TYPE; + @Value("${ode.host-ip:localhost}") + private String hostIP; + private Boolean verboseJson = false; private int importProcessorBufferSize = OdePlugin.INPUT_STREAM_BUFFER_SIZE; - private String hostId; private List uploadLocations = new ArrayList<>(); /* @@ -84,7 +75,7 @@ public class OdeProperties implements EnvironmentAware { // File import properties private String uploadLocationRoot = "uploads"; - private String uploadLocationObuLogLog = "bsmlog"; + private String uploadLocationObuLog = "bsmlog"; private Integer fileWatcherPeriod = 5; // time to wait between processing inbox directory for new files /* @@ -93,17 +84,6 @@ public class OdeProperties implements EnvironmentAware { private int trustRetries = 2; // if trust handshake fails, how many times to retry private int messagesUntilTrustReestablished = 10; // renew trust session every x messages - /* - * Kafka Topics - * - */ - private String[] kafkaTopicsDisabled = { - // disable all POJO topics by default except "topic.OdeBsmPojo". Never - // "topic.OdeBsmPojo because that's the only way to get data into - // "topic.OdeBsmJson - "topic.OdeBsmRxPojo", "topic.OdeBsmTxPojo", "topic.OdeBsmDuringEventPojo", "topic.OdeTimBroadcastPojo" }; - private Set kafkaTopicsDisabledSet = new HashSet<>(); - // BSM private String kafkaTopicOdeBsmPojo = "topic.OdeBsmPojo"; private String kafkaTopicOdeBsmJson = "topic.OdeBsmJson"; @@ -166,8 +146,12 @@ public class OdeProperties implements EnvironmentAware { private String kafkaTopicOdePsmJson = "topic.OdePsmJson"; private int psmReceiverPort = 44940; private int psmBufferSize = 500; + + // Generic Receiver + private int genericReceiverPort = 44990; + private int genericBufferSize = 2000; -// DriverAlerts + // DriverAlerts private String kafkaTopicDriverAlertJson = "topic.OdeDriverAlertJson"; // ASN.1 CODEC @@ -196,64 +180,22 @@ public class OdeProperties implements EnvironmentAware { @PostConstruct void initialize() { - setVersion(buildProperties.getVersion()); logger.info("groupId: {}", buildProperties.getGroup()); logger.info("artifactId: {}", buildProperties.getArtifact()); - logger.info("version: {}", version); + logger.info("version: {}", buildProperties.getVersion()); OdeMsgMetadata.setStaticSchemaVersion(OUTPUT_SCHEMA_VERSION); uploadLocations.add(Paths.get(uploadLocationRoot)); - String hostname; - try { - hostname = InetAddress.getLocalHost().getHostName(); - } catch (UnknownHostException e) { - // Let's just use a random hostname - hostname = UUID.randomUUID().toString(); - logger.error("Unknown host error: {}, using random", e); - } - hostId = hostname; - logger.info("Host ID: {}", hostId); - EventLogger.logger.info("Initializing services on host {}", hostId); - - if (kafkaBrokers == null) { - - logger.warn("ode.kafkaBrokers property not defined. Will try DOCKER_HOST_IP => {}", kafkaBrokers); - - String dockerIp = CommonUtils.getEnvironmentVariable("DOCKER_HOST_IP"); - - if (dockerIp == null) { - logger.warn( - "Neither ode.kafkaBrokers ode property nor DOCKER_HOST_IP environment variable are defined. Defaulting to localhost."); - dockerIp = "localhost"; - } - kafkaBrokers = dockerIp + ":" + DEFAULT_KAFKA_PORT; - - logger.info("Kafka Brokers: {}", kafkaBrokers); - - // URI for the security services /sign endpoint - if (securitySvcsSignatureUri == null) { - securitySvcsSignatureUri = "http://" + dockerIp + ":" + securitySvcsPort + "/" - + securitySvcsSignatureEndpoint; - } + // URI for the security services /sign endpoint + if (securitySvcsSignatureUri == null) { + securitySvcsSignatureUri = "http://" + hostIP + ":" + securitySvcsPort + "/" + + securitySvcsSignatureEndpoint; } - - List asList = Arrays.asList(this.getKafkaTopicsDisabled()); - logger.info("Disabled Topics: {}", asList); - kafkaTopicsDisabledSet.addAll(asList); } - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public List getUploadLocations() { - return this.uploadLocations; + return buildProperties.getVersion(); } public String getProperty(String key) { @@ -268,665 +210,8 @@ public Object getProperty(String key, int i) { return env.getProperty(key, Integer.class, i); } - public String getHostId() { - return hostId; - } - - public String getPluginsLocations() { - return pluginsLocations; - } - - public void setPluginsLocations(String pluginsLocations) { - this.pluginsLocations = pluginsLocations; - } - - public String getKafkaBrokers() { - return kafkaBrokers; - } - - public void setKafkaBrokers(String kafkaBrokers) { - this.kafkaBrokers = kafkaBrokers; - } - - public String getKafkaProducerType() { - return kafkaProducerType; - } - - public void setKafkaProducerType(String kafkaProducerType) { - this.kafkaProducerType = kafkaProducerType; - } - - public Environment getEnv() { - return env; - } - - public void setEnv(Environment env) { - this.env = env; - } - @Override public void setEnvironment(Environment environment) { env = environment; } - - public String getUploadLocationRoot() { - return uploadLocationRoot; - } - - public int getMessagesUntilTrustReestablished() { - return messagesUntilTrustReestablished; - } - - public void setMessagesUntilTrustReestablished(int messagesUntilTrustReestablished) { - this.messagesUntilTrustReestablished = messagesUntilTrustReestablished; - } - - public String getCaCertPath() { - return caCertPath; - } - - public void setCaCertPath(String caCertPath) { - this.caCertPath = caCertPath; - } - - public String getSelfCertPath() { - return selfCertPath; - } - - public void setSelfCertPath(String selfCertPath) { - this.selfCertPath = selfCertPath; - } - - public String getSelfPrivateKeyReconstructionFilePath() { - return selfPrivateKeyReconstructionFilePath; - } - - public void setSelfPrivateKeyReconstructionFilePath(String selfPrivateKeyReconstructionFilePath) { - this.selfPrivateKeyReconstructionFilePath = selfPrivateKeyReconstructionFilePath; - } - - public String getSelfSigningPrivateKeyFilePath() { - return selfSigningPrivateKeyFilePath; - } - - public void setSelfSigningPrivateKeyFilePath(String selfSigningPrivateKeyFilePath) { - this.selfSigningPrivateKeyFilePath = selfSigningPrivateKeyFilePath; - } - - public Boolean getVerboseJson() { - return verboseJson; - } - - public void setVerboseJson(Boolean verboseJson) { - this.verboseJson = verboseJson; - } - - public int getBsmReceiverPort() { - return bsmReceiverPort; - } - - public void setBsmReceiverPort(int bsmReceiverPort) { - this.bsmReceiverPort = bsmReceiverPort; - } - - public int getBsmBufferSize() { - return bsmBufferSize; - } - - public void setBsmBufferSize(int bsmBufferSize) { - this.bsmBufferSize = bsmBufferSize; - } - - public int getTimReceiverPort() { - return timReceiverPort; - } - - public void setTimReceiverPort(int timReceiverPort) { - this.timReceiverPort = timReceiverPort; - } - - public int getTimBufferSize() { - return timBufferSize; - } - - public void setTimBufferSize(int timBufferSize) { - this.timBufferSize = timBufferSize; - } - - public int getSsmReceiverPort() { - return ssmReceiverPort; - } - - public void setSsmReceiverPort(int ssmReceiverPort) { - this.ssmReceiverPort = ssmReceiverPort; - } - - public int getSsmBufferSize() { - return ssmBufferSize; - } - - public void setSsmBufferSize(int ssmBufferSize) { - this.ssmBufferSize = ssmBufferSize; - } - - public int getSrmReceiverPort() { - return srmReceiverPort; - } - - public void setSrmReceiverPort(int srmReceiverPort) { - this.srmReceiverPort = srmReceiverPort; - } - - public int getSrmBufferSize() { - return srmBufferSize; - } - - public void setSrmBufferSize(int srmBufferSize) { - this.srmBufferSize = srmBufferSize; - } - - public int getSpatReceiverPort() { - return spatReceiverPort; - } - - public void setSpatReceiverPort(int spatReceiverPort) { - this.spatReceiverPort = spatReceiverPort; - } - - public int getSpatBufferSize() { - return spatBufferSize; - } - - public void setSpatBufferSize(int spatBufferSize) { - this.spatBufferSize = spatBufferSize; - } - - public int getMapReceiverPort() { - return mapReceiverPort; - } - - public void setMapReceiverPort(int mapReceiverPort) { - this.mapReceiverPort = mapReceiverPort; - } - - public int getMapBufferSize() { - return mapBufferSize; - } - - public void setMapBufferSize(int mapBufferSize) { - this.mapBufferSize = mapBufferSize; - } - - public int getPsmReceiverPort() { - return psmReceiverPort; - } - - public void setPsmReceiverPort(int psmReceiverPort) { - this.psmReceiverPort = psmReceiverPort; - } - - public int getPsmBufferSize() { - return psmBufferSize; - } - - public void setPsmBufferSize(int psmBufferSize) { - this.psmBufferSize = psmBufferSize; - } - - public void setUploadLocationRoot(String uploadLocationRoot) { - this.uploadLocationRoot = uploadLocationRoot; - } - - public int getRsuSrmSlots() { - return rsuSrmSlots; - } - - public void setRsuSrmSlots(int rsuSrmSlots) { - this.rsuSrmSlots = rsuSrmSlots; - } - - public int getTrustRetries() { - return trustRetries; - } - - public void setTrustRetries(int trustRetries) { - this.trustRetries = trustRetries; - } - - public static byte[] getJpoOdeGroupId() { - return JPO_ODE_GROUP_ID; - } - - public int getImportProcessorBufferSize() { - return importProcessorBufferSize; - } - - public void setImportProcessorBufferSize(int importProcessorBufferSize) { - this.importProcessorBufferSize = importProcessorBufferSize; - } - - public String[] getKafkaTopicsDisabled() { - return kafkaTopicsDisabled; - } - - public void setKafkaTopicsDisabled(String[] kafkaTopicsDisabled) { - this.kafkaTopicsDisabled = kafkaTopicsDisabled; - } - - public Set getKafkaTopicsDisabledSet() { - return kafkaTopicsDisabledSet; - } - - public void setKafkaTopicsDisabledSet(Set kafkaTopicsDisabledSet) { - this.kafkaTopicsDisabledSet = kafkaTopicsDisabledSet; - } - - public String getKafkaTopicFilteredOdeBsmJson() { - return kafkaTopicFilteredOdeBsmJson; - } - - public void setKafkaTopicFilteredOdeBsmJson(String kafkaTopicFilteredOdeBsmJson) { - this.kafkaTopicFilteredOdeBsmJson = kafkaTopicFilteredOdeBsmJson; - } - - public String getKafkaTopicOdeBsmPojo() { - return kafkaTopicOdeBsmPojo; - } - - public void setKafkaTopicOdeBsmPojo(String kafkaTopicOdeBsmPojo) { - this.kafkaTopicOdeBsmPojo = kafkaTopicOdeBsmPojo; - } - - public String getKafkaTopicOdeBsmJson() { - return kafkaTopicOdeBsmJson; - } - - public void setKafkaTopicOdeBsmJson(String kafkaTopicOdeBsmJson) { - this.kafkaTopicOdeBsmJson = kafkaTopicOdeBsmJson; - } - - public String getKafkaTopicAsn1DecoderInput() { - return kafkaTopicAsn1DecoderInput; - } - - public void setKafkaTopicAsn1DecoderInput(String kafkaTopicAsn1DecoderInput) { - this.kafkaTopicAsn1DecoderInput = kafkaTopicAsn1DecoderInput; - } - - public String getKafkaTopicAsn1DecoderOutput() { - return kafkaTopicAsn1DecoderOutput; - } - - public void setKafkaTopicAsn1DecoderOutput(String kafkaTopicAsn1DecoderOutput) { - this.kafkaTopicAsn1DecoderOutput = kafkaTopicAsn1DecoderOutput; - } - - public String getKafkaTopicAsn1EncoderInput() { - return kafkaTopicAsn1EncoderInput; - } - - public void setKafkaTopicAsn1EncoderInput(String kafkaTopicAsn1EncoderInput) { - this.kafkaTopicAsn1EncoderInput = kafkaTopicAsn1EncoderInput; - } - - public String getKafkaTopicAsn1EncoderOutput() { - return kafkaTopicAsn1EncoderOutput; - } - - public void setKafkaTopicAsn1EncoderOutput(String kafkaTopicAsn1EncoderOutput) { - this.kafkaTopicAsn1EncoderOutput = kafkaTopicAsn1EncoderOutput; - } - - public String getKafkaTopicOdeDNMsgJson() { - return kafkaTopicOdeDNMsgJson; - } - - public void setKafkaTopicOdeDNMsgJson(String kafkaTopicOdeDNMsgJson) { - this.kafkaTopicOdeDNMsgJson = kafkaTopicOdeDNMsgJson; - } - - public String getKafkaTopicOdeTimJson() { - return kafkaTopicOdeTimJson; - } - - public void setKafkaTopicOdeTimJson(String kafkaTopicOdeTimJson) { - this.kafkaTopicOdeTimJson = kafkaTopicOdeTimJson; - } - - public String getKafkaTopicOdeTimJsonTMCFiltered() { - return kafkaTopicOdeTimJsonTMCFiltered; - } - - public void setKafkaTopicOdeTimJsonTMCFiltered(String kafkaTopicOdeTimJsonTMCFiltered) { - this.kafkaTopicOdeTimJsonTMCFiltered = kafkaTopicOdeTimJsonTMCFiltered; - } - - public String getUploadLocationObuLog() { - return uploadLocationObuLogLog; - } - - public void setUploadLocationObuLog(String uploadLocationObuLog) { - this.uploadLocationObuLogLog = uploadLocationObuLog; - } - - public String getKafkaTopicOdeBsmDuringEventPojo() { - return kafkaTopicOdeBsmDuringEventPojo; - } - - public void setKafkaTopicOdeBsmDuringEventPojo(String kafkaTopicOdeBsmDuringEventPojo) { - this.kafkaTopicOdeBsmDuringEventPojo = kafkaTopicOdeBsmDuringEventPojo; - } - - public String getKafkaTopicOdeBsmRxPojo() { - return kafkaTopicOdeBsmRxPojo; - } - - public void setKafkaTopicOdeBsmRxPojo(String kafkaTopicOdeBsmRxPojo) { - this.kafkaTopicOdeBsmRxPojo = kafkaTopicOdeBsmRxPojo; - } - - public String getKafkaTopicOdeBsmTxPojo() { - return kafkaTopicOdeBsmTxPojo; - } - - public void setKafkaTopicOdeBsmTxPojo(String kafkaTopicOdeBsmTxPojo) { - this.kafkaTopicOdeBsmTxPojo = kafkaTopicOdeBsmTxPojo; - } - - public String getKafkaTopicOdeTimRxJson() { - return kafkaTopicOdeTimRxJson; - } - - public void setKafkaTopicOdeTimRxJson(String kafkaTopicOdeTimRxJson) { - this.kafkaTopicOdeTimRxJson = kafkaTopicOdeTimRxJson; - } - - public String getKafkaTopicOdeTimBroadcastPojo() { - return kafkaTopicOdeTimBroadcastPojo; - } - - public void setKafkaTopicOdeTimBroadcastPojo(String kafkaTopicOdeTimBroadcastPojo) { - this.kafkaTopicOdeTimBroadcastPojo = kafkaTopicOdeTimBroadcastPojo; - } - - public String getKafkaTopicOdeTimBroadcastJson() { - return kafkaTopicOdeTimBroadcastJson; - } - - public void setKafkaTopicOdeTimBroadcastJson(String kafkaTopicOdeTimBroadcastJson) { - this.kafkaTopicOdeTimBroadcastJson = kafkaTopicOdeTimBroadcastJson; - } - - public String getKafkaTopicJ2735TimBroadcastJson() { - return kafkaTopicJ2735TimBroadcastJson; - } - - public void setKafkaTopicJ2735TimBroadcastJson(String kafkaTopicJ2735TimBroadcastJson) { - this.kafkaTopicJ2735TimBroadcastJson = kafkaTopicJ2735TimBroadcastJson; - } - - public String getKafkaTopicFilteredOdeTimJson() { - return kafkaTopicFilteredOdeTimJson; - } - - public void setKafkaTopicFilteredOdeTimJson(String kafkaTopicFilteredOdeTimJson) { - this.kafkaTopicFilteredOdeTimJson = kafkaTopicFilteredOdeTimJson; - } - - public String getKafkaTopicDriverAlertJson() { - return kafkaTopicDriverAlertJson; - } - - public void setKafkaTopicDriverAlertJson(String kafkaTopicDriverAlertJson) { - this.kafkaTopicDriverAlertJson = kafkaTopicDriverAlertJson; - } - - public Integer getFileWatcherPeriod() { - return fileWatcherPeriod; - } - - public void setFileWatcherPeriod(Integer fileWatcherPeriod) { - this.fileWatcherPeriod = fileWatcherPeriod; - } - - public String getSecuritySvcsSignatureUri() { - return securitySvcsSignatureUri; - } - - public void setSecuritySvcsSignatureUri(String securitySvcsSignatureUri) { - this.securitySvcsSignatureUri = securitySvcsSignatureUri; - } - - public String getRsuUsername() { - return rsuUsername; - } - - public void setRsuUsername(String rsuUsername) { - this.rsuUsername = rsuUsername; - } - - public String getRsuPassword() { - return rsuPassword; - } - - public void setRsuPassword(String rsuPassword) { - this.rsuPassword = rsuPassword; - } - - public String getKafkaTopicSdwDepositorInput() { - return kafkaTopicSdwDepositorInput; - } - - public void setKafkaTopicSdwDepositorInput(String kafkaTopicSdwDepositorInput) { - this.kafkaTopicSdwDepositorInput = kafkaTopicSdwDepositorInput; - } - - public String getKafkaTopicSignedOdeTimJsonExpiration() { - return kafkaTopicSignedOdeTimJsonExpiration; - } - public void setKafkaTopicSignedOdeTimJsonExpiration(String kafkaTopicSignedOdeTimJsonExpiration) { - this.kafkaTopicSignedOdeTimJsonExpiration = kafkaTopicSignedOdeTimJsonExpiration; - } - - public String getKafkaTopicOdeSpatTxPojo() { - return kafkaTopicOdeSpatTxPojo; - } - - - public void setKafkaTopicOdeSpatTxPojo(String kafkaTopicOdeSpatTxPojo) { - this.kafkaTopicOdeSpatTxPojo = kafkaTopicOdeSpatTxPojo; - } - - - public String getKafkaTopicOdeSpatPojo() { - return kafkaTopicOdeSpatPojo; - } - - - public void setKafkaTopicOdeSpatPojo(String kafkaTopicOdeSpatPojo) { - this.kafkaTopicOdeSpatPojo = kafkaTopicOdeSpatPojo; - } - - - public String getKafkaTopicOdeSpatJson() { - return kafkaTopicOdeSpatJson; - } - - - public void setKafkaTopicOdeSpatJson(String kafkaTopicOdeSpatJson) { - this.kafkaTopicOdeSpatJson = kafkaTopicOdeSpatJson; - } - - - public String getKafkaTopicOdeSpatRxPojo() { - return kafkaTopicOdeSpatRxPojo; - } - - - public void setKafkaTopicOdeSpatRxPojo(String kafkaTopicOdeSpatRxPojo) { - this.kafkaTopicOdeSpatRxPojo = kafkaTopicOdeSpatRxPojo; - } - - - public String getKafkaTopicOdeSpatRxJson() { - return kafkaTopicOdeSpatRxJson; - } - - - public void setKafkaTopicOdeSpatRxJson(String kafkaTopicOdeSpatRxJson) { - this.kafkaTopicOdeSpatRxJson = kafkaTopicOdeSpatRxJson; - } - - - public String getKafkaTopicFilteredOdeSpatJson() { - return kafkaTopicFilteredOdeSpatJson; - } - - - public void setKafkaTopicFilteredOdeSpatJson(String kafkaTopicFilteredOdeSpatJson) { - this.kafkaTopicFilteredOdeSpatJson = kafkaTopicFilteredOdeSpatJson; - } - - - public String getKafkaTopicOdeRawEncodedBSMJson() { - return kafkaTopicOdeRawEncodedBSMJson; - } - - - public void setKafkaTopicOdeRawEncodedBSMJson(String kafkaTopicOdeRawEncodedBSMJson) { - this.kafkaTopicOdeRawEncodedBSMJson = kafkaTopicOdeRawEncodedBSMJson; - } - - - public String getKafkaTopicOdeRawEncodedTIMJson() { - return kafkaTopicOdeRawEncodedTIMJson; - } - - - public void setKafkaTopicOdeRawEncodedTIMJson(String kafkaTopicOdeRawEncodedTIMJson) { - this.kafkaTopicOdeRawEncodedTIMJson = kafkaTopicOdeRawEncodedTIMJson; - } - - - public String getKafkaTopicOdeRawEncodedSPATJson() { - return kafkaTopicOdeRawEncodedSPATJson; - } - - - public void setKafkaTopicOdeRawEncodedSPATJson(String kafkaTopicOdeRawEncodedSPATJson) { - this.kafkaTopicOdeRawEncodedSPATJson = kafkaTopicOdeRawEncodedSPATJson; - } - - public String getKafkaTopicOdeRawEncodedMAPJson() { - return kafkaTopicOdeRawEncodedMAPJson; - } - - public void setKafkaTopicOdeRawEncodedMAPJson(String kafkaTopicOdeRawEncodedMAPJson) { - this.kafkaTopicOdeRawEncodedMAPJson = kafkaTopicOdeRawEncodedMAPJson; - } - - - public String getKafkaTopicOdeMapTxPojo() { - return kafkaTopicOdeMapTxPojo; - } - - - public void setKafkaTopicOdeMapTxPojo(String kafkaTopicOdeMapTxPojo) { - this.kafkaTopicOdeMapTxPojo = kafkaTopicOdeMapTxPojo; - } - - - public String getKafkaTopicOdeMapJson() { - return kafkaTopicOdeMapJson; - } - - - public void setKafkaTopicOdeMapJson(String kafkaTopicOdeMapJson) { - this.kafkaTopicOdeMapJson = kafkaTopicOdeMapJson; - } - - public String getKafkaTopicOdeRawEncodedPSMJson() { - return kafkaTopicOdeRawEncodedPSMJson; - } - - public void setKafkaTopicOdeRawEncodedPSMJson(String kafkaTopicOdeRawEncodedPSMJson) { - this.kafkaTopicOdeRawEncodedPSMJson = kafkaTopicOdeRawEncodedPSMJson; - } - - - public String getKafkaTopicOdePsmTxPojo() { - return kafkaTopicOdePsmTxPojo; - } - - - public void setKafkaTopicOdePsmTxPojo(String kafkaTopicOdePsmTxPojo) { - this.kafkaTopicOdePsmTxPojo = kafkaTopicOdePsmTxPojo; - } - - - public String getKafkaTopicOdePsmJson() { - return kafkaTopicOdePsmJson; - } - - - public void setKafkaTopicOdePsmJson(String kafkaTopicOdePsmJson) { - this.kafkaTopicOdePsmJson = kafkaTopicOdePsmJson; - } - - public String getKafkaTopicOdeRawEncodedSSMJson() { - return kafkaTopicOdeRawEncodedSSMJson; - } - - public void setKafkaTopicOdeRawEncodedSSMJson(String kafkaTopicOdeRawEncodedSSMJson) { - this.kafkaTopicOdeRawEncodedSSMJson = kafkaTopicOdeRawEncodedSSMJson; - } - - - public String getKafkaTopicOdeSsmPojo() { - return kafkaTopicOdeSsmPojo; - } - - - public void setKafkaTopicOdeSsmPojo(String kafkaTopicOdeSsmPojo) { - this.kafkaTopicOdeSsmPojo = kafkaTopicOdeSsmPojo; - } - - - public String getKafkaTopicOdeSsmJson() { - return kafkaTopicOdeSsmJson; - } - - - public void setKafkaTopicOdeSsmJson(String kafkaTopicOdeSsmJson) { - this.kafkaTopicOdeSsmJson = kafkaTopicOdeSsmJson; - } - - public String getKafkaTopicOdeRawEncodedSRMJson() { - return kafkaTopicOdeRawEncodedSRMJson; - } - - public void setKafkaTopicOdeRawEncodedSRMJson(String kafkaTopicOdeRawEncodedSRMJson) { - this.kafkaTopicOdeRawEncodedSRMJson = kafkaTopicOdeRawEncodedSRMJson; - } - - - public String getKafkaTopicOdeSrmTxPojo() { - return kafkaTopicOdeSrmTxPojo; - } - - - public void setKafkaTopicOdeSrmTxPojo(String kafkaTopicOdeSrmTxPojo) { - this.kafkaTopicOdeSrmTxPojo = kafkaTopicOdeSrmTxPojo; - } - - - public String getKafkaTopicOdeSrmJson() { - return kafkaTopicOdeSrmJson; - } - - - public void setKafkaTopicOdeSrmJson(String kafkaTopicOdeSrmJson) { - this.kafkaTopicOdeSrmJson = kafkaTopicOdeSrmJson; - } - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index b2e2d9be1..5b3457efd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -14,6 +14,8 @@ import java.util.Properties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + public class OdeTimJsonTopology { @@ -21,13 +23,15 @@ public class OdeTimJsonTopology { private final Properties streamsProperties = new Properties(); private OdeProperties odeProperties = new OdeProperties(); + private OdeKafkaProperties odeKafkaProps = new OdeKafkaProperties(); static KafkaStreams streams; - public OdeTimJsonTopology(OdeProperties odeProps) { + public OdeTimJsonTopology(OdeProperties odeProps, OdeKafkaProperties odeKafkaProps) { this.odeProperties = odeProps; - if (this.odeProperties.getKafkaBrokers() != null) { + this.odeKafkaProps = odeKafkaProps; + if (this.odeKafkaProps.getBrokers() != null) { this.streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); - this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeProperties.getKafkaBrokers()); + this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, this.odeKafkaProps.getBrokers()); this.streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass()); this.streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java index 12692de23..21f97de1e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java @@ -17,6 +17,7 @@ import java.util.Properties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.util.SerializableObjectPool; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -25,6 +26,7 @@ public class SerializableMessageProducerPool extends SerializableObjectPoo private static final long serialVersionUID = -2293786403623236678L; transient OdeProperties odeProperties; + transient OdeKafkaProperties odeKafkaProperties; private String brokers; private String type; @@ -32,11 +34,12 @@ public class SerializableMessageProducerPool extends SerializableObjectPoo private Properties props; - public SerializableMessageProducerPool(OdeProperties odeProperties) { + public SerializableMessageProducerPool(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; - this.brokers = odeProperties.getKafkaBrokers(); - this.type = odeProperties.getKafkaProducerType(); + this.odeKafkaProperties = odeKafkaProperties; + this.brokers = odeKafkaProperties.getBrokers(); + this.type = odeKafkaProperties.getProducerType(); this.partitionerClass = odeProperties.getProperty("kafka.partitionerClass"); init(); } @@ -74,7 +77,7 @@ public SerializableMessageProducerPool init() { @Override protected MessageProducer create() { return new MessageProducer<>(brokers, type, partitionerClass, props, - odeProperties.getKafkaTopicsDisabledSet()); + odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java index 29dd242e5..9683e8334 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -26,11 +27,11 @@ public class ByteArrayPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(ByteArrayPublisher.class); protected MessageProducer bytesProducer; - public ByteArrayPublisher(OdeProperties odeProps) { - super(odeProps); + public ByteArrayPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); this.bytesProducer = MessageProducer.defaultByteArrayMessageProducer( - odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index dcd3da77d..74ccd023d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -15,16 +15,16 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import java.io.BufferedInputStream; -import java.nio.file.Path; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; - import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + +import java.io.BufferedInputStream; +import java.nio.file.Path; public class FileAsn1CodecPublisher { @@ -43,9 +43,9 @@ public FileAsn1CodecPublisherException(String string, Exception e) { private LogFileToAsn1CodecPublisher codecPublisher; @Autowired - public FileAsn1CodecPublisher(OdeProperties odeProperties) { + public FileAsn1CodecPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - StringPublisher messagePub = new StringPublisher(odeProperties); + StringPublisher messagePub = new StringPublisher(odeProperties, odeKafkaProperties); this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java index 2dbee2afd..5e47848b0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java @@ -15,23 +15,27 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; +import lombok.Getter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; public abstract class MessagePublisher { private final Logger logger = LoggerFactory.getLogger(this.getClass()); + @Getter + protected OdeKafkaProperties odeKafkaProperties; + // TODO(Matt): remove once all kafka properties are migrated to ODEKafkaProperties and the delegates + @Getter protected OdeProperties odeProperties; - public MessagePublisher(OdeProperties odeProps) { - this.odeProperties = odeProps; - logger.info("Using Brokers: {} of Type: {}", odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType()); + public MessagePublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; + logger.info("Using Brokers: {} of Type: {}", this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType()); } - public OdeProperties getOdeProperties() { - return odeProperties; - } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java index 1cea2e251..d586f0606 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeObject; @@ -28,12 +29,12 @@ public class OdeDataPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer objectProducer; - public OdeDataPublisher(OdeProperties odeProps, String serializer) { - super(odeProps); - this.objectProducer = new MessageProducer<>(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), + public OdeDataPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, String serializer) { + super(odeProperties, odeKafkaProperties); + this.objectProducer = new MessageProducer<>(this.odeKafkaProperties.getBrokers(), + this.odeKafkaProperties.getProducerType(), null, serializer, - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getDisabledTopics()); } public void publish(OdeData msg, String topic) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java index 612c8f3a5..11362a08e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java @@ -18,6 +18,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -27,12 +28,12 @@ public class OdeStringPublisher extends MessagePublisher { private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer stringProducer; - public OdeStringPublisher(OdeProperties odeProps) { - super(odeProps); + public OdeStringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); this.stringProducer = MessageProducer.defaultStringMessageProducer( - odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + this.odeKafkaProperties.getBrokers(), + this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java index d91142775..089d829aa 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java @@ -17,26 +17,25 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; public class StringPublisher extends MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(StringPublisher.class); - protected MessageProducer stringProducer; - - public StringPublisher(OdeProperties odeProps) { - super(odeProps); - this.stringProducer = MessageProducer.defaultStringMessageProducer( - odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - odeProperties.getKafkaTopicsDisabledSet()); + private static final Logger logger = LoggerFactory.getLogger(StringPublisher.class); + protected MessageProducer stringProducer; - } + public StringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(odeProperties, odeKafkaProperties); + this.stringProducer = MessageProducer.defaultStringMessageProducer( + this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), + this.odeKafkaProperties.getDisabledTopics()); - public void publish(String msg, String topic) { - logger.debug("Publishing String data to {}", topic); - stringProducer.send(topic, null, msg); - } + } + public void publish(String msg, String topic) { + logger.debug("Publishing String data to {}", topic); + stringProducer.send(topic, null, msg); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java index 17b9e42c4..075815da5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java @@ -18,7 +18,6 @@ import java.io.BufferedInputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import org.slf4j.Logger; @@ -164,19 +163,25 @@ private void publishList(XmlUtils xmlUtils, List dataList) throws JsonP } else { // Determine the message type (MAP, TIM, SSM, SRM, or PSM) String messageType = UperUtil.determineMessageType(msgPayload); - if (messageType == "MAP") { + if (messageType.equals("MAP")) { publisher.publish(JsonUtils.toJson(odeData, false), publisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); - } else if (messageType == "TIM") { + } else if(messageType.equals("SPAT")){ + publisher.publish(JsonUtils.toJson(odeData, false), + publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + } else if (messageType.equals("TIM")) { publisher.publish(JsonUtils.toJson(odeData, false), publisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); - } else if (messageType == "SSM") { + } else if (messageType.equals("BSM")) { + publisher.publish(JsonUtils.toJson(odeData, false), + publisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); + } else if (messageType.equals("SSM")) { publisher.publish(JsonUtils.toJson(odeData, false), publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSSMJson()); - } else if (messageType == "SRM") { + } else if (messageType.equals("SRM")) { publisher.publish(JsonUtils.toJson(odeData, false), publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSRMJson()); - } else if (messageType == "PSM") { + } else if (messageType.equals("PSM")) { publisher.publish(JsonUtils.toJson(odeData, false), publisher.getOdeProperties().getKafkaTopicOdeRawEncodedPSMJson()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java index 0269fe2ec..a7fa3c011 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java @@ -16,7 +16,8 @@ package us.dot.its.jpo.ode.exporter; import org.springframework.messaging.simp.SimpMessagingTemplate; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /** @@ -24,25 +25,25 @@ */ public class StompStringExporter extends Exporter{ - private OdeProperties odeProperties; + private OdeKafkaProperties odeKafkaProperties; private SimpMessagingTemplate template; private String odeTopic; public StompStringExporter( - OdeProperties odeProperties, + OdeKafkaProperties odeKafkaProperties, String stompTopic, SimpMessagingTemplate template, String odeTopic) { super(stompTopic); - this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; this.template = template; this.odeTopic = odeTopic; } @Override protected void subscribe() { - setConsumer(MessageConsumer.defaultStringMessageConsumer(odeProperties.getKafkaBrokers(), - odeProperties.getHostId() + this.getClass().getSimpleName(), + setConsumer(MessageConsumer.defaultStringMessageConsumer(odeKafkaProperties.getBrokers(), + AppContext.getInstance().getHostId() + this.getClass().getSimpleName(), new StompStringMessageDistributor(template, getTopic()))); getConsumer().setName(this.getClass().getSimpleName()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java index 40194c430..225e8824a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java @@ -24,6 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; public class ImporterDirectoryWatcher implements Runnable { @@ -46,7 +47,7 @@ public enum ImporterFileType { private Integer timePeriod; - public ImporterDirectoryWatcher(OdeProperties odeProperties, Path dir, Path backupDir, Path failureDir, ImporterFileType fileType, Integer timePeriod) { + public ImporterDirectoryWatcher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, Path dir, Path backupDir, Path failureDir, ImporterFileType fileType, Integer timePeriod) { this.inbox = dir; this.backup = backupDir; this.failed = failureDir; @@ -65,7 +66,7 @@ public ImporterDirectoryWatcher(OdeProperties odeProperties, Path dir, Path back logger.error("Error creating directory: " + inbox, e); } - this.importerProcessor = new ImporterProcessor(odeProperties, fileType); + this.importerProcessor = new ImporterProcessor(odeProperties, odeKafkaProperties, fileType); executor = Executors.newScheduledThreadPool(1); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java index 647bc326e..34a00af58 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher.FileAsn1CodecPublisherException; @@ -44,8 +45,8 @@ public class ImporterProcessor { private Pattern gZipPattern = Pattern.compile("application/.*gzip"); private Pattern zipPattern = Pattern.compile("application/.*zip.*"); - public ImporterProcessor(OdeProperties odeProperties, ImporterFileType fileType) { - this.codecPublisher = new FileAsn1CodecPublisher(odeProperties); + public ImporterProcessor(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, ImporterFileType fileType) { + this.codecPublisher = new FileAsn1CodecPublisher(odeProperties, odeKafkaProperties); this.odeProperties = odeProperties; this.fileType = fileType; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java new file mode 100644 index 000000000..dcec01e11 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.Set; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka") +@Data +public class OdeKafkaProperties { + + private static final Logger logger = LoggerFactory.getLogger(OdeKafkaProperties.class); + + @Value("${ode.kafka.brokers:localhost:9092}") + private String brokers; + @Value("${ode.kafka.producer-type:sync}") + private String producerType; + @Value("${ode.kafka.disabled-topics:}") + private Set disabledTopics; +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index 1072b87e7..c4fa2a8a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -30,6 +30,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; @@ -77,7 +78,7 @@ public Asn1CommandManagerException(String msg, Exception e) { private String depositTopic; private RsuDepositor rsuDepositor; - public Asn1CommandManager(OdeProperties odeProperties) { + public Asn1CommandManager(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { this.odeProperties = odeProperties; @@ -86,8 +87,9 @@ public Asn1CommandManager(OdeProperties odeProperties) { try { this.rsuDepositor = new RsuDepositor(odeProperties); this.rsuDepositor.start(); - this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); + this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); this.setDepositTopic(odeProperties.getKafkaTopicSdwDepositorInput()); } catch (Exception e) { String msg = "Error starting SDW depositor"; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index f2b9c393d..37d9e563d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -19,6 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; @@ -50,23 +51,32 @@ public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor srmProducer; private MessageProducer psmProducer; - public Asn1DecodedDataRouter(OdeProperties odeProps) { + public Asn1DecodedDataRouter(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProps; - this.bsmProducer = new MessageProducer<>(odeProps.getKafkaBrokers(), odeProps.getKafkaProducerType(), null, - OdeBsmSerializer.class.getName(), odeProperties.getKafkaTopicsDisabledSet()); - this.timProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.spatProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.mapProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.srmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.psmProducer = MessageProducer.defaultStringMessageProducer(odeProps.getKafkaBrokers(), - odeProps.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); + this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + null, + OdeBsmSerializer.class.getName(), + odeKafkaProperties.getDisabledTopics()); + this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index ad15793fb..cabc556a3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.OdeTimJsonTopology; import us.dot.its.jpo.ode.context.AppContext; @@ -67,15 +68,16 @@ public Asn1EncodedDataRouterException(String string) { private boolean dataSigningEnabledRSU; private boolean dataSigningEnabledSDW; - public Asn1EncodedDataRouter(OdeProperties odeProperties) { + public Asn1EncodedDataRouter(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), this.odeProperties.getKafkaTopicsDisabledSet()); + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); - this.asn1CommandManager = new Asn1CommandManager(odeProperties); + this.asn1CommandManager = new Asn1CommandManager(odeProperties, odeKafkaProperties); this.dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) @@ -86,7 +88,7 @@ public Asn1EncodedDataRouter(OdeProperties odeProperties) { // Initialize and start the OdeTimJsonTopology if it is not already running if (odeTimJsonTopology == null) { - odeTimJsonTopology = new OdeTimJsonTopology(odeProperties); + odeTimJsonTopology = new OdeTimJsonTopology(odeProperties, odeKafkaProperties); if (!odeTimJsonTopology.isRunning()) { odeTimJsonTopology.start(); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index 03ba821d6..2eb86d271 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,11 +15,13 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; +import org.apache.kafka.common.serialization.Serdes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; - +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -30,10 +32,10 @@ public class AsnCodecRouterServiceController { private static final Logger logger = LoggerFactory.getLogger(AsnCodecRouterServiceController.class); - org.apache.kafka.common.serialization.Serdes bas; + Serdes bas; @Autowired - public AsnCodecRouterServiceController(OdeProperties odeProps) { + public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); logger.info("Starting {}", this.getClass().getSimpleName()); @@ -41,10 +43,10 @@ public AsnCodecRouterServiceController(OdeProperties odeProps) { // asn1_codec Decoder Routing logger.info("Routing DECODED data received ASN.1 Decoder"); - Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeProps); + Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeProps, odeKafkaProperties); MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), decoderRouter); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); asn1DecoderConsumer.setName("Asn1DecoderConsumer"); decoderRouter.start(asn1DecoderConsumer, odeProps.getKafkaTopicAsn1DecoderOutput()); @@ -52,10 +54,10 @@ public AsnCodecRouterServiceController(OdeProperties odeProps) { // asn1_codec Encoder Routing logger.info("Routing ENCODED data received ASN.1 Encoder"); - Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps); + Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps, odeKafkaProperties); MessageConsumer encoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), encoderRouter); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), encoderRouter); encoderConsumer.setName("Asn1EncoderConsumer"); encoderRouter.start(encoderConsumer, odeProps.getKafkaTopicAsn1EncoderOutput()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index 49d244cf0..eedf1fa32 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeBSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeBSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getBsmStartFlag()); + public Asn1DecodeBSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getBsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java index 61f821c91..c4df633b4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -21,8 +22,8 @@ public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeMAPJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getMapStartFlag()); + public Asn1DecodeMAPJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getMapStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index 1729348ac..25f96b310 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodePSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodePSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getPsmStartFlag()); + public Asn1DecodePSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getPsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index 33077257f..7223085eb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSPATJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSPATJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSpatStartFlag()); + public Asn1DecodeSPATJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSpatStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 5f726f892..7cd104e9f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSRMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSRMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSrmStartFlag()); + public Asn1DecodeSRMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSrmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index ae9042fa9..e02800c0c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeSSMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSSMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getSsmStartFlag()); + public Asn1DecodeSSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSsmStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index cf612dec1..03f87f8dc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.Asn1Encoding; @@ -20,8 +21,8 @@ public class Asn1DecodeTIMJSON extends AbstractAsn1DecodeMessageJSON { private Logger logger = LoggerFactory.getLogger(this.getClass()); private ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeTIMJSON(OdeProperties odeProps) { - super(new StringPublisher(odeProps), UperUtil.getTimStartFlag()); + public Asn1DecodeTIMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getTimStartFlag()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java index e7954ca46..10281b734 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java @@ -3,8 +3,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -17,69 +19,69 @@ public class AsnCodecMessageServiceController { private static final Logger logger = LoggerFactory.getLogger(AsnCodecMessageServiceController.class); @Autowired - public AsnCodecMessageServiceController(OdeProperties odeProps) { + public AsnCodecMessageServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); logger.info("Starting {} ", this.getClass().getSimpleName()); // asn1_codec Decoder Routing // BSM logger.info("Send encoded BSM to ASN.1 Decoder"); - Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeProps); + Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawBSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeBSMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeBSMJSON); asn1RawBSMJSONConsumer.setName("asn1DecodeBSMJSON"); asn1DecodeBSMJSON.start(asn1RawBSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedBSMJson()); // SPAT logger.info("Send encoded SPAT to ASN.1 Decoder"); - Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeProps); + Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSPATJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSPATJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSPATJSON); asn1RawSPATJSONConsumer.setName("asn1DecodeSPATJSON"); asn1DecodeSPATJSON.start(asn1RawSPATJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSPATJson()); // SSM logger.info("Send encoded SSM to ASN.1 Decoder"); - Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeProps); + Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSSMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSSMJSON); asn1RawSSMJSONConsumer.setName("asn1DecodeSSMJSON"); asn1DecodeSSMJSON.start(asn1RawSSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSSMJson()); // SRM logger.info("Send encoded SRM to ASN.1 Decoder"); - Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeProps); + Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawSRMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeSRMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSRMJSON); asn1RawSRMJSONConsumer.setName("asn1DecodeSRMJSON"); asn1DecodeSRMJSON.start(asn1RawSRMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSRMJson()); // TIM logger.info("Send encoded TIM to ASN.1 Decoder"); - Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeProps); + Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawTIMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeTIMJSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeTIMJSON); asn1RawTIMJSONConsumer.setName("asn1DecodeTIMJSON"); asn1DecodeTIMJSON.start(asn1RawTIMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedTIMJson()); //MAP logger.info("Send encoded MAP to ASN.1 Decoder"); - Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeProps); + Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSON"); asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedMAPJson()); //PSM logger.info("Send encoded PSM to ASN.1 Decoder"); - Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeProps); + Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeProps, odeKafkaProperties); MessageConsumer asn1RawPSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeProps.getKafkaBrokers(), this.getClass().getSimpleName(), asn1DecodePSMSON); + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodePSMSON); asn1RawPSMJSONConsumer.setName("asn1DecodePSMJSON"); asn1DecodePSMSON.start(asn1RawPSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedPSMJson()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java index 942380d87..1f83b856c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java @@ -15,6 +15,7 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.json; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.AbstractSubPubTransformer; @@ -27,11 +28,11 @@ public class ToJsonConverter extends AbstractSubPubTransformer JSON converter launchConverter(odeProps.getKafkaTopicOdeBsmPojo(), OdeBsmDeserializer.class.getName(), - new ToJsonConverter<>(odeProps, false, odeProps.getKafkaTopicOdeBsmJson())); + new ToJsonConverter<>(odeProps, odeKafkaProperties, false, odeProps.getKafkaTopicOdeBsmJson())); } private void launchConverter(String fromTopic, String serializerFQN, ToJsonConverter jsonConverter) { logger.info("Starting JSON converter, converting records from topic {} and publishing to topic {} ", fromTopic, jsonConverter.getOutputTopic()); - MessageConsumer consumer = new MessageConsumer<>(odeProperties.getKafkaBrokers(), + MessageConsumer consumer = new MessageConsumer<>(odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), jsonConverter, serializerFQN); consumer.setName(this.getClass().getName() + fromTopic + "Consumer"); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java index 4299b0075..153d7cb70 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java @@ -25,6 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; @@ -42,7 +43,7 @@ public class FileSystemStorageService implements StorageService { private Path logFileLocation; @Autowired - public FileSystemStorageService(OdeProperties properties) { + public FileSystemStorageService(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties properties) { this.rootLocation = Paths.get(properties.getUploadLocationRoot()); this.logFileLocation = Paths.get(properties.getUploadLocationRoot(), diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 2c060c20b..2e62fc94d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -19,6 +19,8 @@ import java.text.SimpleDateFormat; import java.time.format.DateTimeParseException; import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import org.json.JSONObject; import org.slf4j.Logger; @@ -34,6 +36,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.ConfigEnvironmentVariables; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; @@ -63,12 +67,14 @@ public class TimDepositController { private static final Logger logger = LoggerFactory.getLogger(TimDepositController.class); + private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); private static final String ERRSTR = "error"; private static final String WARNING = "warning"; private static final String SUCCESS = "success"; private OdeProperties odeProperties; + private OdeKafkaProperties odeKafkaProperties; private SerialId serialIdJ2735; private SerialId serialIdOde; @@ -89,23 +95,44 @@ public TimDepositControllerException(String errMsg) { } @Autowired - public TimDepositController(OdeProperties odeProperties) { + public TimDepositController(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { super(); this.odeProperties = odeProperties; + this.odeKafkaProperties = odeKafkaProperties; this.serialIdJ2735 = new SerialId(); this.serialIdOde = new SerialId(); - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeProperties.getKafkaBrokers(), - odeProperties.getKafkaProducerType(), odeProperties.getKafkaTopicsDisabledSet()); - this.timProducer = new MessageProducer<>(odeProperties.getKafkaBrokers(), odeProperties.getKafkaProducerType(), - null, OdeTimSerializer.class.getName(), odeProperties.getKafkaTopicsDisabledSet()); + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) : true; + // start the TIM ingest monitoring service if enabled + boolean timIngestMonitoringEnabled = Boolean.parseBoolean(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); + if (timIngestMonitoringEnabled) { + logger.info("TIM ingest monitoring enabled."); + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + // 3600 seconds, or one hour, was determined to be a sane default for the monitoring interval if monitoring is enabled + // but there was no interval set in the .env file + String interval = odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL); + long monitoringInterval; + try { + monitoringInterval = Long.parseLong(interval); + } catch (NumberFormatException e) { + monitoringInterval = 3600; + } + + scheduledExecutorService.scheduleAtFixedRate(new TimIngestWatcher(monitoringInterval), monitoringInterval, monitoringInterval, java.util.concurrent.TimeUnit.SECONDS); + } else { + logger.info("TIM ingest monitoring disabled."); + } } /** @@ -263,6 +290,8 @@ public synchronized ResponseEntity depositTim(String jsonString, Request return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } + INGEST_MONITOR.incrementTotalMessagesReceived(); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java new file mode 100644 index 000000000..940e200d1 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTracker.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.traveler; + +public class TimIngestTracker { + + private long totalMessagesReceived; + + private TimIngestTracker() { + totalMessagesReceived = 0; + } + + public static TimIngestTracker getInstance() { + return TimIngestMonitorHolder.INSTANCE; + } + + private static class TimIngestMonitorHolder { + private static final TimIngestTracker INSTANCE = new TimIngestTracker(); + } + + public long getTotalMessagesReceived() { + return totalMessagesReceived; + } + + public void incrementTotalMessagesReceived() { + totalMessagesReceived++; + } + + public void resetTotalMessagesReceived() { + totalMessagesReceived = 0; + } + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java new file mode 100644 index 000000000..5de3fa94f --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestWatcher.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.traveler; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TimIngestWatcher implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(TimIngestWatcher.class.getName()); + private final long interval; + + public TimIngestWatcher(long interval) { + this.interval = interval; + } + + @Override + public void run() { + TimIngestTracker tracker = TimIngestTracker.getInstance(); + long ingested = tracker.getTotalMessagesReceived(); + + if (ingested == 0) { + logger.warn("ODE has not received TIM deposits in {} seconds.", interval); + } else { + logger.debug("ODE has received {} TIM deposits in the last {} seconds.", ingested, interval); + } + + // After checking the number of TIMs ingested in the last interval, reset the counter + tracker.resetTotalMessagesReceived(); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java index 96e373ce6..449282c72 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java @@ -1,17 +1,13 @@ package us.dot.its.jpo.ode.udp; import java.net.DatagramSocket; -import java.net.DatagramPacket; import java.net.SocketException; -import org.apache.tomcat.util.buf.HexUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.uper.UperUtil; public abstract class AbstractUdpReceiverPublisher implements Runnable { @@ -43,38 +39,17 @@ public void setStopped(boolean stopped) { this.stopped = stopped; } - @Autowired - public AbstractUdpReceiverPublisher(OdeProperties odeProps, int port, int bufferSize) { + protected AbstractUdpReceiverPublisher(OdeProperties odeProps, int port, int bufferSize) { this.odeProperties = odeProps; this.port = port; this.bufferSize = bufferSize; try { - socket = new DatagramSocket(this.port); + this.socket = new DatagramSocket(this.port); logger.info("Created UDP socket bound to port {}", this.port); } catch (SocketException e) { logger.error("Error creating socket with port " + this.port, e); } } - public OdeAsn1Payload getPayloadHexString(DatagramPacket packet, UperUtil.SupportedMessageTypes msgType) { - String startFlag = UperUtil.getStartFlag(msgType); - // extract the actual packet from the buffer - byte[] payload = packet.getData(); - if (payload == null) - return null; - // convert bytes to hex string and verify identity - String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); - if (payloadHexString.indexOf(startFlag) == -1) - return null; - - logger.debug("Full {} packet: {}", msgType, payloadHexString); - payloadHexString = UperUtil.stripDot3Header(payloadHexString, startFlag); - logger.debug("Stripped {} packet: {}", msgType, payloadHexString); - - OdeAsn1Payload timPayload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - - return timPayload; - } - } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java new file mode 100644 index 000000000..bd62c7d0f --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java @@ -0,0 +1,238 @@ +package us.dot.its.jpo.ode.udp; + +import java.net.DatagramPacket; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +import org.apache.tomcat.util.buf.HexUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import us.dot.its.jpo.ode.model.OdeAsn1Data; +import us.dot.its.jpo.ode.model.OdeAsn1Payload; +import us.dot.its.jpo.ode.model.OdeBsmMetadata; +import us.dot.its.jpo.ode.model.OdeBsmMetadata.BsmSource; +import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; +import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; +import us.dot.its.jpo.ode.model.OdeLogMsgMetadataLocation; +import us.dot.its.jpo.ode.model.OdeMapMetadata; +import us.dot.its.jpo.ode.model.OdeMapMetadata.MapSource; +import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; +import us.dot.its.jpo.ode.model.OdePsmMetadata; +import us.dot.its.jpo.ode.model.OdePsmMetadata.PsmSource; +import us.dot.its.jpo.ode.model.OdeSpatMetadata; +import us.dot.its.jpo.ode.model.OdeSpatMetadata.SpatSource; +import us.dot.its.jpo.ode.model.OdeSrmMetadata; +import us.dot.its.jpo.ode.model.OdeSrmMetadata.SrmSource; +import us.dot.its.jpo.ode.model.OdeSsmMetadata; +import us.dot.its.jpo.ode.model.OdeSsmMetadata.SsmSource; +import us.dot.its.jpo.ode.model.OdeTimMetadata; +import us.dot.its.jpo.ode.model.ReceivedMessageDetails; +import us.dot.its.jpo.ode.model.RxSource; +import us.dot.its.jpo.ode.uper.UperUtil; +import us.dot.its.jpo.ode.util.JsonUtils; + +public class UdpHexDecoder { + + private static Logger logger = LoggerFactory.getLogger(UdpHexDecoder.class); + + public static OdeAsn1Payload getPayloadHexString(DatagramPacket packet, UperUtil.SupportedMessageTypes msgType) { + String startFlag = UperUtil.getStartFlag(msgType); + // extract the actual packet from the buffer + byte[] payload = packet.getData(); + if (payload == null) + return null; + // convert bytes to hex string and verify identity + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + if (payloadHexString.indexOf(startFlag) == -1) + return null; + + logger.debug("Full {} packet: {}", msgType, payloadHexString); + + payloadHexString = UperUtil.stripTrailingZeros(UperUtil.stripDot3Header(payloadHexString, startFlag)).toLowerCase(); + logger.debug("Stripped {} packet: {}", msgType, payloadHexString); + + OdeAsn1Payload odePayload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + + return odePayload; + } + + public static String buildJsonMapFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload mapPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.MAP); + if (mapPayload == null) + return null; + OdeMapMetadata mapMetadata = new OdeMapMetadata(mapPayload); + + // Add header data for the decoding process + mapMetadata.setOdeReceivedAt(getUtcTimeString()); + + mapMetadata.setOriginIp(senderIp); + mapMetadata.setMapSource(MapSource.RSU); + mapMetadata.setRecordType(RecordType.mapTx); + mapMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + mapMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(mapMetadata, mapPayload), false); + } + + public static String buildJsonSpatFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload spatPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SPAT); + if (spatPayload == null) + return null; + OdeSpatMetadata spatMetadata = new OdeSpatMetadata(spatPayload); + + // Add header data for the decoding process + spatMetadata.setOdeReceivedAt(getUtcTimeString()); + + spatMetadata.setOriginIp(senderIp); + spatMetadata.setSpatSource(SpatSource.RSU); + spatMetadata.setRecordType(RecordType.spatTx); + spatMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + spatMetadata.setSecurityResultCode(SecurityResultCode.success); + + + return JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false); + } + + public static String buildJsonTimFromPacket(DatagramPacket packet){ + + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload timPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.TIM); + if (timPayload == null) + return null; + OdeTimMetadata timMetadata = new OdeTimMetadata(timPayload); + + // Add header data for the decoding process + timMetadata.setOdeReceivedAt(getUtcTimeString()); + + timMetadata.setOriginIp(senderIp); + timMetadata.setRecordType(RecordType.timMsg); + timMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + timMetadata.setSecurityResultCode(SecurityResultCode.success); + return JsonUtils.toJson(new OdeAsn1Data(timMetadata, timPayload), false); + } + + public static String buildJsonBsmFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + OdeAsn1Payload bsmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.BSM); + if (bsmPayload == null) + return null; + OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); + + // Set BSM Metadata values that can be assumed from the UDP endpoint + bsmMetadata.setOdeReceivedAt(getUtcTimeString()); + + ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); + OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( + "unavailable", + "unavailable", + "unavailable", + "unavailable", + "unavailable"); + receivedMessageDetails.setRxSource(RxSource.RSU); + receivedMessageDetails.setLocationData(locationData); + bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); + + bsmMetadata.setOriginIp(senderIp); + bsmMetadata.setBsmSource(BsmSource.EV); + bsmMetadata.setRecordType(RecordType.bsmTx); + bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); + bsmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false); + } + + public static String buildJsonSsmFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload ssmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SSM); + if (ssmPayload == null) + return null; + OdeSsmMetadata ssmMetadata = new OdeSsmMetadata(ssmPayload); + + // Add header data for the decoding process + ssmMetadata.setOdeReceivedAt(getUtcTimeString()); + + ssmMetadata.setOriginIp(senderIp); + ssmMetadata.setSsmSource(SsmSource.RSU); + ssmMetadata.setRecordType(RecordType.ssmTx); + ssmMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + ssmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(ssmMetadata, ssmPayload), false); + } + + public static String buildJsonSrmFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload srmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SRM); + if (srmPayload == null) + return null; + OdeSrmMetadata srmMetadata = new OdeSrmMetadata(srmPayload); + + // Add header data for the decoding process + srmMetadata.setOdeReceivedAt(getUtcTimeString()); + + srmMetadata.setOriginIp(senderIp); + srmMetadata.setSrmSource(SrmSource.RSU); + srmMetadata.setRecordType(RecordType.srmTx); + srmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); + srmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(srmMetadata, srmPayload), false); + } + + public static String buildJsonPsmFromPacket(DatagramPacket packet){ + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload psmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.PSM); + if (psmPayload == null) + return null; + OdePsmMetadata psmMetadata = new OdePsmMetadata(psmPayload); + // Add header data for the decoding process + psmMetadata.setOdeReceivedAt(getUtcTimeString()); + + psmMetadata.setOriginIp(senderIp); + psmMetadata.setPsmSource(PsmSource.RSU); + psmMetadata.setRecordType(RecordType.psmTx); + psmMetadata.setRecordGeneratedBy(GeneratedBy.UNKNOWN); + psmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(psmMetadata, psmPayload), false); + } + + public static String getUtcTimeString(){ + ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); + String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); + return timestamp; + } + + +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index b8b252f48..fe1707a33 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -1,47 +1,32 @@ package us.dot.its.jpo.ode.udp.bsm; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeBsmMetadata; -import us.dot.its.jpo.ode.model.OdeBsmMetadata.BsmSource; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeLogMsgMetadataLocation; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.ReceivedMessageDetails; -import us.dot.its.jpo.ode.model.RxSource; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class BsmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(BsmReceiver.class); - private StringPublisher bsmPublisher; + private final StringPublisher bsmPublisher; @Autowired - public BsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getBsmReceiverPort(), odeProps.getBsmBufferSize()); - - this.bsmPublisher = new StringPublisher(odeProps); + public BsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getBsmReceiverPort(), odeProps.getBsmBufferSize()); } - public BsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public BsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.bsmPublisher = new StringPublisher(odeProps); + this.bsmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -56,47 +41,21 @@ public void run() { do { try { logger.debug("Waiting for UDP BSM packets..."); - socket.receive(packet); + this.socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload bsmPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.BSM); - if (bsmPayload == null) - continue; - OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); - - // Set BSM Metadata values that can be assumed from the UDP endpoint - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - bsmMetadata.setOdeReceivedAt(timestamp); + String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); - OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( - "unavailable", - "unavailable", - "unavailable", - "unavailable", - "unavailable"); - receivedMessageDetails.setRxSource(RxSource.RSU); - receivedMessageDetails.setLocationData(locationData); - bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); - - bsmMetadata.setOriginIp(senderIp); - bsmMetadata.setBsmSource(BsmSource.EV); - bsmMetadata.setRecordType(RecordType.bsmTx); - bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); - bsmMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - bsmPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false), - bsmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); + if(bsmJson != null){ + bsmPublisher.publish(bsmJson, bsmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); + } + + } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index f16c657bd..3df7a4c2c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -3,16 +3,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.bsm.BsmReceiver; -import us.dot.its.jpo.ode.udp.tim.TimReceiver; -import us.dot.its.jpo.ode.udp.ssm.SsmReceiver; -import us.dot.its.jpo.ode.udp.srm.SrmReceiver; -import us.dot.its.jpo.ode.udp.spat.SpatReceiver; +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.psm.PsmReceiver; +import us.dot.its.jpo.ode.udp.spat.SpatReceiver; +import us.dot.its.jpo.ode.udp.srm.SrmReceiver; +import us.dot.its.jpo.ode.udp.ssm.SsmReceiver; +import us.dot.its.jpo.ode.udp.tim.TimReceiver; /** * Centralized UDP service dispatcher. @@ -24,7 +27,7 @@ public class UdpServicesController { private Logger logger = LoggerFactory.getLogger(UdpServicesController.class); @Autowired - public UdpServicesController(OdeProperties odeProps) { + public UdpServicesController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { super(); // Start the UDP receivers @@ -33,25 +36,28 @@ public UdpServicesController(OdeProperties odeProps) { logger.debug("Starting UDP receiver services..."); // BSM internal - rm.submit(new BsmReceiver(odeProps)); + rm.submit(new BsmReceiver(odeProps, odeKafkaProperties)); // TIM internal - rm.submit(new TimReceiver(odeProps)); + rm.submit(new TimReceiver(odeProps, odeKafkaProperties)); // SSM internal port - rm.submit(new SsmReceiver(odeProps)); + rm.submit(new SsmReceiver(odeProps, odeKafkaProperties)); // SRM internal port - rm.submit(new SrmReceiver(odeProps)); + rm.submit(new SrmReceiver(odeProps, odeKafkaProperties)); // SPAT internal port - rm.submit(new SpatReceiver(odeProps)); + rm.submit(new SpatReceiver(odeProps, odeKafkaProperties)); // MAP internal port - rm.submit(new MapReceiver(odeProps)); + rm.submit(new MapReceiver(odeProps, odeKafkaProperties)); // PSM internal port - rm.submit(new PsmReceiver(odeProps)); + rm.submit(new PsmReceiver(odeProps, odeKafkaProperties)); + + // Generic Receiver internal port + rm.submit(new GenericReceiver(odeProps, odeKafkaProperties)); logger.debug("UDP receiver services started."); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java new file mode 100644 index 000000000..2d6e7bb50 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -0,0 +1,112 @@ +package us.dot.its.jpo.ode.udp.generic; + +import java.net.DatagramPacket; +import org.apache.tomcat.util.buf.HexUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.uper.UperUtil; + +public class GenericReceiver extends AbstractUdpReceiverPublisher { + + private static Logger logger = LoggerFactory.getLogger(GenericReceiver.class); + + private final StringPublisher publisher; + + @Autowired + public GenericReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getGenericReceiverPort(), odeProps.getGenericBufferSize()); + } + + public GenericReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { + super(odeProps, port, bufferSize); + + this.publisher = new StringPublisher(odeProperties, odeKafkaProperties); + } + + @Override + public void run() { + + logger.debug("Generic UDP Receiver Service started."); + + byte[] buffer = new byte[bufferSize]; + + + + do { + buffer = new byte[bufferSize]; + // packet should be recreated on each loop to prevent latent data in buffer + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + try { + logger.debug("Waiting for Generic UDP packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + senderIp = packet.getAddress().getHostAddress(); + senderPort = packet.getPort(); + logger.debug("Packet received from {}:{}", senderIp, senderPort); + + byte[] payload = packet.getData(); + if (payload == null){ + logger.debug("Skipping Null Payload"); + continue; + } + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + logger.debug("Raw Payload" + payloadHexString); + + String messageType = UperUtil.determineHexPacketType(payloadHexString); + + logger.debug("Detected Message Type {}", messageType); + + if (messageType.equals("MAP")) { + String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); + logger.debug("Sending Data to Topic" + mapJson); + if(mapJson != null){ + publisher.publish(mapJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); + } + } else if(messageType.equals("SPAT")) { + String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); + if(spatJson != null){ + publisher.publish(spatJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + } + } else if (messageType.equals("TIM")) { + String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); + if(timJson != null){ + publisher.publish(timJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); + } + } else if (messageType.equals("BSM")) { + String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); + if(bsmJson!=null){ + publisher.publish(bsmJson, this.odeProperties.getKafkaTopicOdeRawEncodedBSMJson()); + } + } else if (messageType.equals("SSM")) { + String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); + if(ssmJson!=null){ + publisher.publish(ssmJson, this.odeProperties.getKafkaTopicOdeRawEncodedSSMJson()); + } + } else if (messageType.equals("SRM")) { + String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); + if(srmJson!=null){ + publisher.publish(srmJson, this.odeProperties.getKafkaTopicOdeRawEncodedSRMJson()); + } + } else if (messageType.equals("PSM")) { + String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); + if(psmJson!=null){ + publisher.publish(psmJson, this.odeProperties.getKafkaTopicOdeRawEncodedPSMJson()); + } + }else{ + logger.debug("Unknown Message Type"); + } + } + } catch (Exception e) { + logger.error("Error receiving packet", e); + } + } while (!isStopped()); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index d77b15cf2..bf9b4fe5d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -1,43 +1,31 @@ package us.dot.its.jpo.ode.udp.map; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMapMetadata.MapSource; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeMapMetadata; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class MapReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(MapReceiver.class); - private StringPublisher mapPublisher; + private final StringPublisher mapPublisher; @Autowired - public MapReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getMapReceiverPort(), odeProps.getMapBufferSize()); - - this.mapPublisher = new StringPublisher(odeProps); + public MapReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getMapReceiverPort(), odeProps.getMapBufferSize()); } - public MapReceiver(OdeProperties odeProps, int port, int bufferSize) { + public MapReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.mapPublisher = new StringPublisher(odeProps); + this.mapPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -54,34 +42,19 @@ public void run() { logger.debug("Waiting for UDP Map packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload mapPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.MAP); - if (mapPayload == null) - continue; - OdeMapMetadata mapMetadata = new OdeMapMetadata(mapPayload); - - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - mapMetadata.setOdeReceivedAt(timestamp); - - mapMetadata.setOriginIp(senderIp); - mapMetadata.setMapSource(MapSource.RSU); - mapMetadata.setRecordType(RecordType.mapTx); - mapMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - mapMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - mapPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(mapMetadata, mapPayload), false), - mapPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); + + String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); + if(mapJson != null){ + mapPublisher.publish(mapJson, mapPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); + } + } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index 7bd56c95c..d535b067b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -1,26 +1,16 @@ package us.dot.its.jpo.ode.udp.psm; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdePsmMetadata.PsmSource; -import us.dot.its.jpo.ode.model.OdePsmMetadata; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class PsmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(PsmReceiver.class); @@ -28,16 +18,14 @@ public class PsmReceiver extends AbstractUdpReceiverPublisher { private StringPublisher psmPublisher; @Autowired - public PsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getPsmReceiverPort(), odeProps.getPsmBufferSize()); - - this.psmPublisher = new StringPublisher(odeProps); + public PsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getPsmReceiverPort(), odeProps.getPsmBufferSize()); } - public PsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public PsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.psmPublisher = new StringPublisher(odeProps); + this.psmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -54,34 +42,16 @@ public void run() { logger.debug("Waiting for UDP PSM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload psmPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.PSM); - if (psmPayload == null) - continue; - OdePsmMetadata psmMetadata = new OdePsmMetadata(psmPayload); - - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - psmMetadata.setOdeReceivedAt(timestamp); - - psmMetadata.setOriginIp(senderIp); - psmMetadata.setPsmSource(PsmSource.RSU); - psmMetadata.setRecordType(RecordType.psmTx); - psmMetadata.setRecordGeneratedBy(GeneratedBy.UNKNOWN); - psmMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - psmPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(psmMetadata, psmPayload), false), - psmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedPSMJson()); + String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); + if(psmJson != null){ + psmPublisher.publish(psmJson, psmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedPSMJson()); + } } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index 5bb7bd8ef..cb8ed0e5a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -1,43 +1,31 @@ package us.dot.its.jpo.ode.udp.spat; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeSpatMetadata; -import us.dot.its.jpo.ode.model.OdeSpatMetadata.SpatSource; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class SpatReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SpatReceiver.class); - private StringPublisher spatPublisher; + private final StringPublisher spatPublisher; @Autowired - public SpatReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSpatReceiverPort(), odeProps.getSpatBufferSize()); - - this.spatPublisher = new StringPublisher(odeProps); + public SpatReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSpatReceiverPort(), odeProps.getSpatBufferSize()); } - public SpatReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SpatReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.spatPublisher = new StringPublisher(odeProps); + this.spatPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -54,34 +42,17 @@ public void run() { logger.debug("Waiting for UDP SPaT packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload spatPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SPAT); - if (spatPayload == null) - continue; - OdeSpatMetadata spatMetadata = new OdeSpatMetadata(spatPayload); - - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - spatMetadata.setOdeReceivedAt(timestamp); - - spatMetadata.setOriginIp(senderIp); - spatMetadata.setSpatSource(SpatSource.RSU); - spatMetadata.setRecordType(RecordType.spatTx); - spatMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - spatMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - spatPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false), - spatPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); + if(spatJson != null){ + spatPublisher.publish(spatJson,spatPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + } } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index b9d9121bd..a541a080d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -1,43 +1,31 @@ package us.dot.its.jpo.ode.udp.srm; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeSrmMetadata; -import us.dot.its.jpo.ode.model.OdeSrmMetadata.SrmSource; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class SrmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SrmReceiver.class); - private StringPublisher srmPublisher; + private final StringPublisher srmPublisher; @Autowired - public SrmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSrmReceiverPort(), odeProps.getSrmBufferSize()); - - this.srmPublisher = new StringPublisher(odeProps); + public SrmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSrmReceiverPort(), odeProps.getSrmBufferSize()); } - public SrmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SrmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.srmPublisher = new StringPublisher(odeProps); + this.srmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -54,34 +42,17 @@ public void run() { logger.debug("Waiting for UDP SRM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload srmPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SRM); - if (srmPayload == null) - continue; - OdeSrmMetadata srmMetadata = new OdeSrmMetadata(srmPayload); - - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - srmMetadata.setOdeReceivedAt(timestamp); - - srmMetadata.setOriginIp(senderIp); - srmMetadata.setSrmSource(SrmSource.RSU); - srmMetadata.setRecordType(RecordType.srmTx); - srmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); - srmMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - srmPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(srmMetadata, srmPayload), false), - srmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSRMJson()); + + String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); + if(srmJson != null){ + srmPublisher.publish(srmJson, srmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSRMJson()); + } } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index 27108eec7..f193fbcfd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -1,43 +1,31 @@ package us.dot.its.jpo.ode.udp.ssm; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeSsmMetadata; -import us.dot.its.jpo.ode.model.OdeSsmMetadata.SsmSource; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class SsmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SsmReceiver.class); - private StringPublisher ssmPublisher; + private final StringPublisher ssmPublisher; @Autowired - public SsmReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getSsmReceiverPort(), odeProps.getSsmBufferSize()); - - this.ssmPublisher = new StringPublisher(odeProps); + public SsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getSsmReceiverPort(), odeProps.getSsmBufferSize()); } - public SsmReceiver(OdeProperties odeProps, int port, int bufferSize) { + public SsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.ssmPublisher = new StringPublisher(odeProps); + this.ssmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -54,34 +42,19 @@ public void run() { logger.debug("Waiting for UDP SSM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload ssmPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SSM); - if (ssmPayload == null) - continue; - OdeSsmMetadata ssmMetadata = new OdeSsmMetadata(ssmPayload); + + String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - ssmMetadata.setOdeReceivedAt(timestamp); - - ssmMetadata.setOriginIp(senderIp); - ssmMetadata.setSsmSource(SsmSource.RSU); - ssmMetadata.setRecordType(RecordType.ssmTx); - ssmMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - ssmMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - ssmPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(ssmMetadata, ssmPayload), false), - ssmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSSMJson()); + if(ssmJson!=null){ + ssmPublisher.publish(ssmJson, ssmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSSMJson()); + } + } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 5524463fe..87c4894b7 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -1,25 +1,17 @@ package us.dot.its.jpo.ode.udp.tim; import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.model.OdeLogMetadata.SecurityResultCode; -import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeTimMetadata; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; -import us.dot.its.jpo.ode.uper.UperUtil; -import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.udp.UdpHexDecoder; public class TimReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(TimReceiver.class); @@ -27,16 +19,14 @@ public class TimReceiver extends AbstractUdpReceiverPublisher { private StringPublisher timPublisher; @Autowired - public TimReceiver(OdeProperties odeProps) { - this(odeProps, odeProps.getTimReceiverPort(), odeProps.getTimBufferSize()); - - this.timPublisher = new StringPublisher(odeProps); + public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + this(odeProps, odeKafkaProperties, odeProps.getTimReceiverPort(), odeProps.getTimBufferSize()); } - public TimReceiver(OdeProperties odeProps, int port, int bufferSize) { + public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { super(odeProps, port, bufferSize); - this.timPublisher = new StringPublisher(odeProps); + this.timPublisher = new StringPublisher(odeProperties, odeKafkaProperties); } @Override @@ -52,33 +42,18 @@ public void run() { logger.debug("Waiting for UDP TIM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload timPayload = super.getPayloadHexString(packet, UperUtil.SupportedMessageTypes.TIM); - if (timPayload == null) - continue; - OdeTimMetadata timMetadata = new OdeTimMetadata(timPayload); - - // Add header data for the decoding process - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - timMetadata.setOdeReceivedAt(timestamp); - - timMetadata.setOriginIp(senderIp); - timMetadata.setRecordType(RecordType.timMsg); - timMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - timMetadata.setSecurityResultCode(SecurityResultCode.success); - - // Submit JSON to the OdeRawEncodedMessageJson Kafka Topic - timPublisher.publish(JsonUtils.toJson(new OdeAsn1Data(timMetadata, timPayload), false), - timPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); + + String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); + if(timJson != null){ + timPublisher.publish(timJson, timPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); + } + } } catch (Exception e) { logger.error("Error receiving packet", e); } } while (!isStopped()); } + + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java index 6261744c8..04cb4cc46 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java @@ -30,7 +30,7 @@ public enum SupportedMessageTypes { // Strips the IEEE 1609.2 security header (if it exists) and returns the payload public static String stripDot2Header(String hexString, String payload_start_flag) { hexString = hexString.toLowerCase(); - int startIndex = hexString.indexOf(payload_start_flag); + int startIndex = findValidStartFlagLocation(hexString, payload_start_flag); if (startIndex == -1) return "BAD DATA"; String strippedPayload = stripTrailingZeros(hexString.substring(startIndex, hexString.length())); @@ -43,15 +43,16 @@ public static String stripDot2Header(String hexString, String payload_start_flag * Otherwise, returns just the payload. */ public static byte[] stripDot3Header(byte[] packet, HashMap msgStartFlags) { + String hexString = HexUtils.toHexString(packet); String hexPacketParsed = ""; - + for (String start_flag : msgStartFlags.values()) { - int payloadStartIndex = hexString.indexOf(start_flag); - - if (payloadStartIndex == -1) + int payloadStartIndex = findValidStartFlagLocation(hexString, start_flag); + if (payloadStartIndex == -1){ continue; - + } + String headers = hexString.substring(0, payloadStartIndex); String payload = hexString.substring(payloadStartIndex, hexString.length()); @@ -81,7 +82,7 @@ public static byte[] stripDot3Header(byte[] packet, HashMap msgS * Otherwise, returns just the payload. */ public static String stripDot3Header(String hexString, String payload_start_flag) { - int payloadStartIndex = hexString.indexOf(payload_start_flag); + int payloadStartIndex = findValidStartFlagLocation(hexString,payload_start_flag); String headers = hexString.substring(0, payloadStartIndex); String payload = hexString.substring(payloadStartIndex, hexString.length()); logger.debug("Base payload: " + payload); @@ -95,41 +96,72 @@ public static String stripDot3Header(String hexString, String payload_start_flag return headers.substring(signedDot2StartIndex, headers.length()) + strippedPayload; } - /** - * Determines the message type based off the most likely start flag - * - * @param payload The OdeMsgPayload to check the content of. - */ + /** + * Determines the message type based off the most likely start flag + * + * @param payload The OdeMsgPayload to check the content of. + */ public static String determineMessageType(OdeMsgPayload payload) { String messageType = ""; try { JSONObject payloadJson = JsonUtils.toJSONObject(payload.getData().toJson()); String hexString = payloadJson.getString("bytes").toLowerCase(); + hexString = stripTrailingZeros(hexString); + messageType = determineHexPacketType(hexString); - HashMap flagIndexes = new HashMap(); - flagIndexes.put("MAP", hexString.indexOf(MAP_START_FLAG)); - flagIndexes.put("TIM", hexString.indexOf(TIM_START_FLAG)); - flagIndexes.put("SSM", hexString.indexOf(SSM_START_FLAG)); - flagIndexes.put("PSM", hexString.indexOf(PSM_START_FLAG)); - flagIndexes.put("SRM", hexString.indexOf(SRM_START_FLAG)); - - int lowestIndex = Integer.MAX_VALUE; - for (String key : flagIndexes.keySet()) { - if (flagIndexes.get(key) == -1) { - logger.debug("This message is not of type " + key); - continue; - } - if (flagIndexes.get(key) < lowestIndex) { - messageType = key; - lowestIndex = flagIndexes.get(key); - } - } } catch (JsonUtilsException e) { logger.error("JsonUtilsException while checking message header. Stacktrace: " + e.toString()); } return messageType; } + public static String determineHexPacketType(String hexString){ + + String messageType = ""; + HashMap flagIndexes = new HashMap(); + + flagIndexes.put("MAP", findValidStartFlagLocation(hexString, MAP_START_FLAG)); + flagIndexes.put("SPAT", findValidStartFlagLocation(hexString, SPAT_START_FLAG)); + flagIndexes.put("TIM", findValidStartFlagLocation(hexString, TIM_START_FLAG)); + flagIndexes.put("BSM", findValidStartFlagLocation(hexString, BSM_START_FLAG)); + flagIndexes.put("SSM", findValidStartFlagLocation(hexString, SSM_START_FLAG)); + flagIndexes.put("PSM", findValidStartFlagLocation(hexString, PSM_START_FLAG)); + flagIndexes.put("SRM", findValidStartFlagLocation(hexString, SRM_START_FLAG)); + + int lowestIndex = Integer.MAX_VALUE; + for (String key : flagIndexes.keySet()) { + if (flagIndexes.get(key) == -1) { + logger.debug("This message is not of type " + key); + continue; + } + if (flagIndexes.get(key) < lowestIndex) { + messageType = key; + lowestIndex = flagIndexes.get(key); + } + } + return messageType; + } + + public static int findValidStartFlagLocation(String hexString, String startFlag){ + int index = hexString.indexOf(startFlag); + + // If the message has a header, make sure not to missidentify the message by the header + + if(index == 0 || index == -1){ + return index; + } + else{ + index = hexString.indexOf(startFlag,4); + } + + // Make sure start flag is on an even numbered byte + while(index != -1 && index %2 != 0){ + index = hexString.indexOf(startFlag, index+1); + } + return index; + } + + /** * Trims extra `00` bytes off of the end of an ASN1 payload string * This is remove the padded bytes added to the payload when receiving ASN1 payloads diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java index 7ad63c352..44c88d9a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java @@ -33,6 +33,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.exporter.StompStringExporter; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; @@ -51,8 +52,8 @@ public class FileUploadController { @Autowired public FileUploadController( - StorageService storageService, OdeProperties odeProperties, - SimpMessagingTemplate template) { + StorageService storageService, OdeProperties odeProperties, + OdeKafkaProperties odeKafkaProperties, SimpMessagingTemplate template) { super(); this.storageService = storageService; @@ -67,21 +68,21 @@ public FileUploadController( logger.debug("UPLOADER - Backup directory: {}", backupPath); // Create the importers that watch folders for new/modified files - threadPool.submit(new ImporterDirectoryWatcher(odeProperties, logPath, backupPath, failurePath, ImporterFileType.LOG_FILE, odeProperties.getFileWatcherPeriod())); + threadPool.submit(new ImporterDirectoryWatcher(odeProperties, odeKafkaProperties, logPath, backupPath, failurePath, ImporterFileType.LOG_FILE, odeProperties.getFileWatcherPeriod())); // Create unfiltered exporters - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSpatJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeMapJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSrmJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicDriverAlertJson())); - threadPool.submit(new StompStringExporter(odeProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimBroadcastJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeBsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSpatJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeMapJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSrmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicDriverAlertJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimBroadcastJson())); // Create filtered exporters - threadPool.submit(new StompStringExporter(odeProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeTimJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeBsmJson())); + threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeTimJson())); } @PostMapping("/upload/{type}") diff --git a/jpo-ode-svcs/src/main/resources/application.properties b/jpo-ode-svcs/src/main/resources/application.properties deleted file mode 100644 index 4fe1e2faa..000000000 --- a/jpo-ode-svcs/src/main/resources/application.properties +++ /dev/null @@ -1,61 +0,0 @@ -#General Properties -#================== -groupId=${project.groupId} -artifactId=${project.artifactId} -version=${project.version} -#server.port = 8443 -#server.ssl.key-store = classpath:jpo_ode_keystore.jks -#server.ssl.key-store-password = keystore_pass -#server.ssl.key-password = key_pass - -spring.http.multipart.max-file-size=1MB -spring.http.multipart.max-request-size=1MB - -#ode.kafkaBrokers = localhost:9092 -#ode.verboseJson = false - -#File import properties -#ode.uploadLocation = uploads -#ode.uploadLocationBsm = bsm -#ode.uploadLocationMessageFrame = messageframe - -#USDOT Situation Data Clearinghouse (SDC) / Situational Data Exchange (SDX) Properties -#========================================================================================================================= - -#RSU Properties (note - do not include quotes) -#-------------- -#ode.rsuUsername = -#ode.rsuPassword = - -#Security Properties -#------------------- -#ode.caCertPath = path/to/CaCertFile or define env variable ${ODE_CA_CERT_PATH} -#ode.selfCertPath = path/to/selfCertFile or define env variable ${ODE_SELF_CERT_PATH} -#ode.selfPrivateKeyReconstructionFilePath = path/to/selfPrivateKeyReconstructionFile or define env variable ${ODE_SELF_PRIVATE_KEY_RECONSTRUCTION_FILE_PATH} -#ode.selfSigningPrivateKeyFilePath = path/to/selfSigningPrivateKeyFile or define env variable ${ODE_SELF_SIGNING_PRIVATE_KEY_FILE_PATH} -#ode.securitySvcsSignatureUri= // The URI for signing data using the jpo-security-svcs module. Normally doesn't need to be set because ODE will calculate it based on DOCKER_HOST_IP. If the service is deployed outside Docker, it should be set to http://host:ip/sign of the server it's running on - -#Kafka Topics -#ode.kafkaTopicsDisabled = topic.OdeBsmRxPojo topic.OdeBsmTxPojo topic.OdeBsmDuringEventPojo topic.OdeTimBroadcastPojo -#BSM -#ode.kafkaTopicOdeBsmPojo = topic.OdeBsmPojo -#ode.kafkaTopicOdeBsmJson = topic.OdeBsmJson -#ode.kafkaTopicOdeBsmRxPojo= topic.OdeBsmRxPojo -#ode.kafkaTopicOdeBsmTxPojo= topic.OdeBsmTxPojo -#ode.kafkaTopicOdeBsmDuringEventPojo= topic.OdeBsmDuringEventPojo -#ode.kafkaTopicFilteredOdeBsmJson = topic.FilteredOdeBsmJson - -#TIM -#ode.kafkaTopicOdeTimPojo = topic.OdeTimPojo -#ode.kafkaTopicOdeTimJson = topic.OdeTimJson -#ode.kafkaTopicOdeDNMsgJson= topic.OdeDNMsgJson -#ode.kafkaTopicOdeDNMsgPojo= topic.OdeDNMsgPojo -#ode.kafkaTopicOdeTimRxJson= topic.OdeTimRxJson -#ode.kafkaTopicOdeTimBroadcastPojo= topic.OdeTimBroadcastPojo -#ode.kafkaTopicOdeTimBroadcastJson= topic.OdeTimBroadcastJson - -#ASN.1 CODEC -#ode.kafkaTopicAsn1DecoderInput = topic.Asn1DecoderInput -#ode.kafkaTopicAsn1DecoderOutput = topic.Asn1DecoderOutput -#ode.kafkaTopicAsn1EncoderInput = topic.Asn1EncoderInput -#ode.kafkaTopicAsn1EncoderOutput = topic.Asn1EncoderOutput diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml new file mode 100644 index 000000000..63d2f31fc --- /dev/null +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -0,0 +1,15 @@ +spring: + http: + multipart: + max-file-size: 1MB + max-request-size: 1MB +ode: + host-ip: ${DOCKER_HOST_IP} + kafka: + brokers: ${DOCKER_HOST_IP}:9092 + producer-type: sync + disabled-topics: + - "topic.OdeBsmRxPojo" + - "topic.OdeBsmTxPojo" + - "topic.OdeBsmDuringEventPojo" + - "topic.OdeTimBroadcastPojo" diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index b0f2e9cfd..e8d699966 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -16,12 +16,8 @@ package us.dot.its.jpo.ode; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.HashSet; -import java.util.Set; - import org.junit.jupiter.api.Test; import org.springframework.boot.info.BuildProperties; import org.springframework.core.env.Environment; @@ -32,7 +28,7 @@ import mockit.Tested; import us.dot.its.jpo.ode.util.CommonUtils; -public class OdePropertiesTest { +class OdePropertiesTest { @Tested OdeProperties testOdeProperties; @@ -45,7 +41,7 @@ public class OdePropertiesTest { CommonUtils capturingCommonUtils; @Test - public void testInit() { + void testInit() { new Expectations() { { } @@ -58,14 +54,8 @@ public void testInit() { } @Test - public void testSettersAndGetters() { - - String testDdsCasPassword = "testDdsCasPassword123456"; - String testDdsCasUrl = "testDdsCasUrl123456"; - String testDdsCasUsername = "testDdsCasUsername123456"; - String testDdsWebsocketUrl = "testDdsWebsocketUrl123456"; - String testKafkaBrokers = "testKafkaBrokers123456"; - String testKafkaProducerType = "testKafkaProducerType123456"; + void testSettersAndGetters() { + String testPluginsLocations = "testpluginsLocations123456"; String testUploadLocationObuLog = "testuploadLocationObuLog123456"; String testUploadLocationRoot = "testUploadLocationRoot123456"; @@ -80,13 +70,8 @@ public void testSettersAndGetters() { int testTrustRetries = 23; String testKafkaTopicOdeBsmPojo = "testKafkaTopicOdeBsmPojo"; String testKafkaTopicOdeBsmJson = "testKafkaTopicOdeBsmJson"; - String testVersion = "1.1.0-SNAPSHOT"; int testImportProcessorBufferSize = 83; - String[] testKafkaTopicsDisabled = new String[] { "testKafkaTopicsDisabled0" }; - Set testKafkaTopicsDisabledSet = new HashSet<>(); - testKafkaTopicsDisabledSet.add("testKafkaTopicsDisabledSet0"); - String testKafkaTopicAsn1DecoderInput = "testKafkaTopicAsn1DecoderInput"; String testKafkaTopicAsn1DecoderOutput = "testKafkaTopicAsn1DecoderOutput"; String testKafkaTopicAsn1EncoderInput = "testKafkaTopicAsn1EncoderInput"; @@ -109,10 +94,9 @@ public void testSettersAndGetters() { String testRsuUsername = "testRsuUsername"; String testRsuPassword = "testRsuPassword"; + testOdeProperties.setHostIP("test-host"); testOdeProperties.setEnv(mockEnv); testOdeProperties.setEnvironment(mockEnv); - testOdeProperties.setKafkaBrokers(testKafkaBrokers); - testOdeProperties.setKafkaProducerType(testKafkaProducerType); testOdeProperties.setPluginsLocations(testPluginsLocations); testOdeProperties.setUploadLocationObuLog(testUploadLocationObuLog); testOdeProperties.setUploadLocationRoot(testUploadLocationRoot); @@ -127,10 +111,7 @@ public void testSettersAndGetters() { testOdeProperties.setTrustRetries(testTrustRetries); testOdeProperties.setKafkaTopicOdeBsmPojo(testKafkaTopicOdeBsmPojo); testOdeProperties.setKafkaTopicOdeBsmJson(testKafkaTopicOdeBsmJson); - testOdeProperties.setVersion(testVersion); testOdeProperties.setImportProcessorBufferSize(testImportProcessorBufferSize); - testOdeProperties.setKafkaTopicsDisabled(testKafkaTopicsDisabled); - testOdeProperties.setKafkaTopicsDisabledSet(testKafkaTopicsDisabledSet); testOdeProperties.setKafkaTopicAsn1DecoderInput(testKafkaTopicAsn1DecoderInput); testOdeProperties.setKafkaTopicAsn1DecoderOutput(testKafkaTopicAsn1DecoderOutput); @@ -154,10 +135,8 @@ public void testSettersAndGetters() { testOdeProperties.setRsuUsername(testRsuUsername); testOdeProperties.setRsuPassword(testRsuPassword); + assertEquals("test-host", testOdeProperties.getHostIP()); assertEquals("Incorrect testEnv", mockEnv, testOdeProperties.getEnv()); - assertEquals("Incorrect testKafkaBrokers", testKafkaBrokers, testOdeProperties.getKafkaBrokers()); - assertEquals("Incorrect testKafkaProducerType", testKafkaProducerType, - testOdeProperties.getKafkaProducerType()); assertEquals("Incorrect testpluginsLocations", testPluginsLocations, testOdeProperties.getPluginsLocations()); assertEquals("Incorrect testUploadLocationObuLog", testUploadLocationObuLog, @@ -181,13 +160,8 @@ public void testSettersAndGetters() { testOdeProperties.getKafkaTopicOdeBsmPojo()); assertEquals("Incorrect testKafkaTopicOdeBsmJson", testKafkaTopicOdeBsmJson, testOdeProperties.getKafkaTopicOdeBsmJson()); - assertEquals("Incorrect testVersion", testVersion, testOdeProperties.getVersion()); assertEquals("Incorrect testImportProcessorBufferSize", testImportProcessorBufferSize, testOdeProperties.getImportProcessorBufferSize()); - assertEquals("Incorrect testKafkaTopicsDisabled", testKafkaTopicsDisabled[0], - testOdeProperties.getKafkaTopicsDisabled()[0]); - assertTrue("Incorrect testKafkaTopicsDisabledSet", - testOdeProperties.getKafkaTopicsDisabledSet().contains("testKafkaTopicsDisabledSet0")); assertEquals("Incorrect testKafkaTopicAsn1DecoderInput", testKafkaTopicAsn1DecoderInput, testOdeProperties.getKafkaTopicAsn1DecoderInput()); @@ -229,8 +203,6 @@ public void testSettersAndGetters() { assertEquals("Incorrect testRsuUsername", testRsuUsername, testOdeProperties.getRsuUsername()); assertEquals("Incorrect RsuPassword", testRsuPassword, testOdeProperties.getRsuPassword()); - OdeProperties.getJpoOdeGroupId(); - testOdeProperties.getHostId(); testOdeProperties.getProperty("testProperty"); testOdeProperties.getProperty("testProperty", 5); testOdeProperties.getProperty("testProperty", "testDefaultValue"); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java index 669d94469..c757d22c5 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java @@ -4,12 +4,21 @@ import org.apache.kafka.streams.StoreQueryParameters; import org.apache.kafka.streams.Topology; import org.apache.kafka.streams.state.ReadOnlyKeyValueStore; +import org.junit.jupiter.api.AfterEach; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.AfterEach; -import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; public class OdeTimJsonTopologyTest { @@ -18,11 +27,13 @@ public class OdeTimJsonTopologyTest { private KafkaStreams mockStreams; private ReadOnlyKeyValueStore mockStore; private OdeProperties mockOdeProps; + private OdeKafkaProperties mockOdeKafkaProps; @BeforeEach public void setUp() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { mockOdeProps = mock(OdeProperties.class); - odeTimJsonTopology = new OdeTimJsonTopology(mockOdeProps); + mockOdeKafkaProps = mock(OdeKafkaProperties.class); + odeTimJsonTopology = new OdeTimJsonTopology(mockOdeProps, mockOdeKafkaProps); mockStreams = mock(KafkaStreams.class); mockStore = mock(ReadOnlyKeyValueStore.class); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java index 96de098f2..4a9f76bb1 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java @@ -26,7 +26,6 @@ import org.apache.kafka.clients.producer.Producer; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import mockit.Expectations; import mockit.Injectable; @@ -34,6 +33,7 @@ import mockit.Tested; import mockit.Verifications; //import mockit.integration.junit4.JMockit; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; //@RunWith(JMockit.class) @@ -43,6 +43,8 @@ public class SerializableMessageProducerPoolTest { SerializableMessageProducerPool testSerializableMessageProducerPool; @Injectable OdeProperties mockOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; @BeforeEach public void setUp() { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java index 3d4d132d6..b483d67dc 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java @@ -22,6 +22,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -32,6 +33,8 @@ public class ByteArrayPublisherTest { @Injectable OdeProperties testOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String testSerializer; @Mocked byte[] mockOdeBsmData; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java index d6b297b4f..c77e1ceed 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java @@ -22,6 +22,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeData; @@ -34,6 +35,8 @@ public class OdeDataPublisherTest { @Injectable OdeProperties testOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String testSerializer; @Mocked OdeBsmData mockOdeBsmData; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java index 5723a5c0b..0fd875644 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java @@ -21,6 +21,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -33,6 +34,9 @@ public class OdeStringPublisherTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java index 0229be360..5488b8fb0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java @@ -18,22 +18,18 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; -//import mockit.integration.junit4.JMockit; import static org.junit.Assert.*; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.messaging.simp.SimpMessagingTemplate; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; -//@RunWith(JMockit.class) -public class ExporterTest { +class ExporterTest { - @Test - public void shouldRun(@Mocked OdeProperties mockOdeProperties, + void shouldRun(@Mocked OdeKafkaProperties odeKafkaProperties, @Injectable SimpMessagingTemplate mockSimpMessagingTemplate, @Mocked final MessageConsumer mockByteArrayConsumer, @Mocked final MessageConsumer mockStringConsumer) { @@ -42,10 +38,7 @@ public void shouldRun(@Mocked OdeProperties mockOdeProperties, new Expectations() { { - mockOdeProperties.getKafkaBrokers(); - result = anyString; - - mockOdeProperties.getHostId(); + odeKafkaProperties.getBrokers(); result = anyString; mockStringConsumer.close(); @@ -53,9 +46,9 @@ public void shouldRun(@Mocked OdeProperties mockOdeProperties, }; try { - Exporter odeBsmExporter = new StompStringExporter( - mockOdeProperties, testTopic, mockSimpMessagingTemplate, - "odeTopic"); + Exporter odeBsmExporter = new StompStringExporter(odeKafkaProperties, + testTopic, + mockSimpMessagingTemplate, "odeTopic"); odeBsmExporter.setConsumer(mockStringConsumer); odeBsmExporter.run(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java index ac892bd65..1046052ba 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java @@ -18,6 +18,7 @@ import mockit.*; import org.junit.jupiter.api.Test; import org.springframework.messaging.simp.SimpMessagingTemplate; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; @@ -30,6 +31,8 @@ public class StompStringExporterTest { @Injectable OdeProperties injectableOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable String stompTopic = "testTopic"; @Injectable SimpMessagingTemplate simpMessagingTemplate; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java index 02bd8bfe5..35b3df2b4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java @@ -28,6 +28,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; @@ -39,6 +40,8 @@ public class ImporterDirectoryWatcherTest { @Injectable OdeProperties injectableOdeProperties; @Injectable + OdeKafkaProperties odeKafkaProperties; + @Injectable Path inbox; @Injectable Path failureDir; @@ -87,7 +90,7 @@ public void testRun() throws InterruptedException, IOException { mockScheduledExecutorService.awaitTermination(anyLong, TimeUnit.SECONDS); } }; - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, backupDir, failureDir, backupDir, injectableImporterFileType, timePeriod); + testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, backupDir, failureDir, backupDir, injectableImporterFileType, timePeriod); testImporterDirectoryWatcher.run(); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java index 32e43b921..69f984fb2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java @@ -35,6 +35,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; @@ -45,6 +46,8 @@ public class ImporterDirectoryWatcherTestOld { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties odeKafkaProperties; @Mocked Path mockDir; @Injectable @@ -78,7 +81,7 @@ public void createTestObject() { } catch (IOException e) { fail("Unexpected exception in expectations block: " + e); } - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); + testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); testImporterDirectoryWatcher.setWatching(false); } @@ -94,7 +97,7 @@ public void testConstructorOdeUtilsException() { } catch (IOException e) { fail("Unexpected exception in expectations block: " + e); } - new ImporterDirectoryWatcher(injectableOdeProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); + new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); } @Test diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java new file mode 100644 index 000000000..1f23358ba --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class OdeKafkaPropertiesTest { + + @Autowired + private OdeKafkaProperties odeKafkaProperties; + + @Test + void testGetBrokers() { + assertEquals("localhost:9092", odeKafkaProperties.getBrokers()); + } + + @Test + void testGetProducerType() { + assertEquals("sync", odeKafkaProperties.getProducerType()); + } + + @Test + void testGetKafkaTopicsDisabled() { + Set kafkaTopicsDisabled = odeKafkaProperties.getDisabledTopics(); + assertEquals(4, kafkaTopicsDisabled.size()); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmRxPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmTxPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmDuringEventPojo")); + assertTrue(kafkaTopicsDisabled.contains("topic.OdeTimBroadcastPojo")); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index 47cdb0b11..b8d8415c0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -22,14 +22,12 @@ import org.junit.jupiter.api.Test; import mockit.Capturing; -import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeTravelerInputData; -import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; -import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal.RequestVerb; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; import us.dot.its.jpo.ode.snmp.SnmpSession; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -42,6 +40,9 @@ public class Asn1CommandManagerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; @Capturing diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java index 3cad9e9e1..c4db680b7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java @@ -20,9 +20,9 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; @@ -39,6 +39,8 @@ public class AsnCodecRouterServiceControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties odeKafkaProperties; @Test @Disabled public void shouldStartTwoConsumers() { @@ -50,7 +52,7 @@ public void shouldStartTwoConsumers() { } }; - assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties)); + assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties, odeKafkaProperties)); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index af86ea450..f29edca97 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeBsmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeBSMJSONTest { - private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedBSMJson(), "topic.OdeRawEncodedBSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); - - // Validate the metadata - OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getBsmSource(), OdeBsmMetadata.BsmSource.EV); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeBSMJSONTest { + private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals(properties.getKafkaTopicOdeRawEncodedBSMJson(), "topic.OdeRawEncodedBSMJson"); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + + Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); + + // Validate the metadata + OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeBsmMetadata.BsmSource.EV, jsonMetadataObj.getBsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java index 02c6a0c7f..dda58a276 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java @@ -1,46 +1,55 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMapMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeMAPJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedMAPJson(), "topic.OdeRawEncodedMAPJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); - - // Validate the metadata - OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getMapSource(), OdeMapMetadata.MapSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeMAPJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedMAPJson", properties.getKafkaTopicOdeRawEncodedMAPJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); + + // Validate the metadata + OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeMapMetadata.MapSource.RSU, jsonMetadataObj.getMapSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index 5c7ed84f8..6dcf1ecd0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) public class Asn1DecodePSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedPSMJson(), "topic.OdeRawEncodedPSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); - - // Validate the metadata - OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getPsmSource(), OdePsmMetadata.PsmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + public void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals(properties.getKafkaTopicOdeRawEncodedPSMJson(), "topic.OdeRawEncodedPSMJson"); + } + + @Test + public void testProcess() throws XmlUtilsException, JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); + + // Validate the metadata + OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); + assertEquals(jsonMetadataObj.getPsmSource(), OdePsmMetadata.PsmSource.RSU); + assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); + assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); + assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); + assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index 47c6bb773..a9ae8c31c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSpatMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -public class Asn1DecodeSPATJSONTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSPATJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSPATJson(), "topic.OdeRawEncodedSPATJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); - - // Validate the metadata - OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSpatSource(), OdeSpatMetadata.SpatSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + + assertEquals("topic.OdeRawEncodedSPATJson", properties.getKafkaTopicOdeRawEncodedSPATJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); + + // Validate the metadata + OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSpatMetadata.SpatSource.RSU, jsonMetadataObj.getSpatSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index 3a0944d2e..ac29a8145 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -1,46 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSrmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeSRMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSRMJson(), "topic.OdeRawEncodedSRMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); - - // Validate the metadata - OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSrmSource(), OdeSrmMetadata.SrmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSRMJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedSRMJson", properties.getKafkaTopicOdeRawEncodedSRMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + + Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); + + // Validate the metadata + OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSrmMetadata.SrmSource.RSU, jsonMetadataObj.getSrmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 84bb81734..26a702d07 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -1,46 +1,55 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSsmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class Asn1DecodeSSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedSSMJson(), "topic.OdeRawEncodedSSMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); - - // Validate the metadata - OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getSsmSource(), OdeSsmMetadata.SsmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeSSMJSONTest { + private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedSSMJson", properties.getKafkaTopicOdeRawEncodedSSMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); + + // Validate the metadata + OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSsmMetadata.SsmSource.RSU, jsonMetadataObj.getSsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index 4df22112f..d4f6786f3 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -1,47 +1,56 @@ package us.dot.its.jpo.ode.services.asn1.message; -import static org.junit.jupiter.api.Assertions.assertEquals; - import org.json.JSONException; import org.junit.jupiter.api.Test; - +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -public class Asn1DecodeTIMJSONTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class Asn1DecodeTIMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - assertEquals(properties.getKafkaTopicOdeRawEncodedTIMJson(), "topic.OdeRawEncodedTIMJson"); - } - - @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - properties.setKafkaBrokers("localhost:9092"); - Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(properties); - - OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); - - // Validate the metadata - OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getRecordGeneratedBy(), OdeMsgMetadata.GeneratedBy.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); - } + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testConstructor() { + OdeProperties properties = new OdeProperties(); + assertEquals("topic.OdeRawEncodedTIMJson", properties.getKafkaTopicOdeRawEncodedTIMJson()); + } + + @Test + void testProcess() throws JSONException { + OdeProperties properties = new OdeProperties(); + Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(properties, odeKafkaProperties); + + OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); + + // Validate the metadata + OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeMsgMetadata.GeneratedBy.RSU, jsonMetadataObj.getRecordGeneratedBy()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java index 2cf131c7e..bed8866d9 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java @@ -1,19 +1,31 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + import static org.junit.Assert.assertNotNull; -import org.junit.jupiter.api.Test; +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) +class AsnCodecMessageServiceControllerTest { -import us.dot.its.jpo.ode.OdeProperties; - -public class AsnCodecMessageServiceControllerTest { + @Autowired + OdeKafkaProperties odeKafkaProps; + + @Test + void shouldStartTwoConsumers() { + OdeProperties odeProps = new OdeProperties(); - @Test - public void shouldStartTwoConsumers() { - OdeProperties odeProps = new OdeProperties(); - odeProps.setKafkaBrokers("localhost:9092"); - AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeProps); - assertNotNull(asnCodecMessageServiceController); - } + AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeProps, odeKafkaProps); + assertNotNull(asnCodecMessageServiceController); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java index 44d736835..1a3f905e2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java @@ -21,6 +21,7 @@ import mockit.Injectable; import mockit.Mocked; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -33,6 +34,8 @@ public class ToJsonConverterTest { @Injectable OdeProperties mockOdeProperties; @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable boolean mockVerbose; @Injectable String mockTopic; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java index b703558d3..bee54d235 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java @@ -17,9 +17,9 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; @@ -27,7 +27,9 @@ public class ToJsonServiceControllerTest { @Injectable - OdeProperties injectableOdeProperties; + OdeProperties odeProperties; + @Injectable + OdeKafkaProperties mockOdeKafkaProperties; // @Capturing // ToJsonConverter capturingToJsonConverter; @@ -38,7 +40,7 @@ public class ToJsonServiceControllerTest { public void test() { new Expectations() { { - new ToJsonConverter<>((OdeProperties) any, anyBoolean, anyString); + new ToJsonConverter<>((OdeProperties) any, (OdeKafkaProperties) any, anyBoolean, anyString); times = 1; new MessageConsumer<>(anyString, anyString, (MessageProcessor) any, anyString); @@ -46,7 +48,7 @@ public void test() { } }; - new ToJsonServiceController(injectableOdeProperties); + new ToJsonServiceController(odeProperties, mockOdeKafkaProperties); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 911a77919..f0e21e19a 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -15,9 +15,8 @@ ******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import static org.junit.Assert.assertEquals; - import org.apache.commons.io.IOUtils; +import static org.junit.Assert.assertEquals; import org.junit.jupiter.api.Test; import org.springframework.http.ResponseEntity; @@ -28,6 +27,7 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; @@ -38,6 +38,7 @@ import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; import us.dot.its.jpo.ode.wrapper.MessageProducer; + public class TimDepositControllerTest { @Tested @@ -46,6 +47,9 @@ public class TimDepositControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Capturing MessageProducer capturingMessageProducer; @@ -167,6 +171,15 @@ public void testDepositingTimWithExtraProperties(@Capturing TimTransmogrifier ca assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); } + @Test + public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { + String timToSubmit = "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; + long priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); + ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived()); + } + @Test public void testSuccessfulRsuMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"sspTimRights\": \"1\", \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"sspLocationRights\": \"1\", \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"sspMsgTypes\": \"1\", \"sspMsgContent\": \"1\", \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java new file mode 100644 index 000000000..f9ae23735 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerTest.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.traveler; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +public class TimIngestTrackerTest { + + @Test + public void testCanIncrementTotalMessagesReceived() { + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + long priorCount = testTimIngestTracker.getTotalMessagesReceived(); + testTimIngestTracker.incrementTotalMessagesReceived(); + assertTrue(testTimIngestTracker.getTotalMessagesReceived() > priorCount); + } + + @Test + public void testCanResetTotalMessagesReceived() { + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + testTimIngestTracker.incrementTotalMessagesReceived(); + assertTrue(testTimIngestTracker.getTotalMessagesReceived()> 0); + testTimIngestTracker.resetTotalMessagesReceived(); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java new file mode 100644 index 000000000..51947277d --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestWatcherTest.java @@ -0,0 +1,18 @@ +package us.dot.its.jpo.ode.traveler; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; + +public class TimIngestWatcherTest { + + @Test + public void testRun() { + TimIngestWatcher watcher = new TimIngestWatcher(0); + watcher.run(); + + // we can't easily test that the run method wrote the correct log message, but we can test that it reset the total messages received after running + TimIngestTracker testTimIngestTracker = TimIngestTracker.getInstance(); + assertEquals(0, testTimIngestTracker.getTotalMessagesReceived()); + } + +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java index c83b30afd..1d56aca12 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java @@ -18,8 +18,6 @@ import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; -import mockit.Mock; -import mockit.MockUp; import mockit.Mocked; import org.junit.jupiter.api.BeforeEach; @@ -27,6 +25,7 @@ import org.springframework.http.HttpStatus; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.multipart.MultipartFile; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; @@ -47,6 +46,9 @@ public class FileUploadControllerTest { @Injectable OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable SimpMessagingTemplate injectableSimpMessagingTemplate; @@ -79,8 +81,8 @@ public void constructorShouldLaunchSevenThreads() { times = 11; } }; - testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, - injectableSimpMessagingTemplate); + testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, injectableOdeKafkaProperties, + injectableSimpMessagingTemplate); } @Test diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml new file mode 100644 index 000000000..cd3de12c1 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -0,0 +1,10 @@ +ode: + host-ip: test-host + kafka: + brokers: localhost:9092 + producer-type: sync + disabled-topics: + - "topic.OdeBsmRxPojo" + - "topic.OdeBsmTxPojo" + - "topic.OdeBsmDuringEventPojo" + - "topic.OdeTimBroadcastPojo" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4463b2307..4e563673a 100644 --- a/pom.xml +++ b/pom.xml @@ -93,6 +93,12 @@ 5.9.3 test + + org.projectlombok + lombok + 1.18.30 + annotationProcessor + diff --git a/sample.env b/sample.env index 9cbb1645f..625ceff5f 100644 --- a/sample.env +++ b/sample.env @@ -15,7 +15,7 @@ #################### # General Properties -# (Required) The IP address of Docker host machine which can be found by running "ifconfig" +# (Required) The IP address of Docker host machine which can be found by running "ip -4 addr" # Hint: look for "inet addr:" within "eth0" or "en0" for OSX DOCKER_HOST_IP= @@ -103,4 +103,10 @@ AEM_LOG_TO_FILE=false AEM_LOG_LEVEL=INFO ADM_LOG_TO_FILE=false ADM_LOG_TO_CONSOLE=true -ADM_LOG_LEVEL=INFO \ No newline at end of file +ADM_LOG_LEVEL=INFO + +# ODE Monitoring +ODE_TIM_INGEST_MONITORING_ENABLED=true +# The interval is measured in seconds. 60 seconds is a sane default for local monitoring, but you may want to increase +# the interval to 3600 (1 hour) or more for production monitoring to reduce the noise in logs for healthy systems +ODE_TIM_INGEST_MONITORING_INTERVAL=60 \ No newline at end of file diff --git a/scripts/tests/udpsender_generic.py b/scripts/tests/udpsender_generic.py new file mode 100644 index 000000000..80dd0a823 --- /dev/null +++ b/scripts/tests/udpsender_generic.py @@ -0,0 +1,33 @@ +import socket +import time +import os + +BSM_MESSAGE = "0022e12d18466c65c1493800000e00e4616183e85a8f0100c000038081bc001480b8494c4c950cd8cde6e9651116579f22a424dd78fffff00761e4fd7eb7d07f7fff80005f11d1020214c1c0ffc7c016aff4017a0ff65403b0fd204c20ffccc04f8fe40c420ffe6404cefe60e9a10133408fcfde1438103ab4138f00e1eec1048ec160103e237410445c171104e26bc103dc4154305c2c84103b1c1c8f0a82f42103f34262d1123198103dac25fb12034ce10381c259f12038ca103574251b10e3b2210324c23ad0f23d8efffe0000209340d10000004264bf00" +MAP_MESSAGE = "001283c138003000205e9c014d3eab092ca624b5518202dc3658042800000400023622c60ca009f66d48abfaf81388d8ad18070027d9b2ffcfe9804f13667b1ffd009ec2c76e3ffc82c4e0001004b00c5000000800066c4574101813ecd8b757fae027d9b30e6ff5604ec363561fe7809ec6cd69bfec813c4d8a617fc9027d9b2147008604fb163666000016250000802580228000001000096229e1309b51a6fe4204dd361cf1fe5009f6018e1000096020a00000080004d88a57f84027d9b3827002804ec36087600a009f62c289407282c310001c0440188800000006c46dbe02813ec5816d800710052200000001b11b6fad404fb16054a0000401c8800000006c47b3d24813ec5816d801b100c4200000000af890f12c580007e87100d4200000008af4c0f12c580077e7a2c0004000160002001cb028d000000800052c160bc40b5fffd8a9409d86bfebb5b40141457fef53b76c008b467014145800080002bffcbffc82c6a0001804b024d000000800036c2213c3b013ecd80096d64027d9affd8cdfc04f635ff7983bc09f66c0082aa2014280b1b80006012c0b3400000100004b02bcf0f6d7fe065d602788b0138eb900b1240001012c083400000080009b0c2af0b804fb15fe6de171afff6c63e04ec15fe1de670060e40002581ea8000004000135da6df0180a0a6adc2c00d0143cd51897fda028c8abb25001a0b0680008012c105400000200009aedbefae005053540ee003c0a326a9cf3fed8143c5667780010582c0004009608aa00000080004d76de7ee402829aba88ffdc050f354525fff80a322bcf23fa602c690000c04b0395000000200016bb4fbd4e01414d3215800802940ab108fff2030d2000110126200000001aee5103be050a15f6f1ffc8404d8800000006bb97c18e0142857dfa800010146200000001aee89099a050a15f8720000b05dd000000800046be3743b781428d80e1b00002879b00514b4404f63600827d8c09e22c000400015ffe6007016190000402582ce8000004000135ecee1de80a146c02e54758143cd8059ad3e027b1b00613dd004f102c360000804b055d000000200046bcc7c3c781428d80108c6e02829b002b2ece050a16019a4b29b00ab5c3604f136004e410409ec018a10000960c3a00000080004d7de9878602851b003923cc05053601623b440a0a6bfb8c3a5014140b0640005012c197400000100005afe570ef2050a36003a47c80a0a6bfd2c45f014140b054000501101a8200000001b05a90edc050535ffe605800a0a101b8200000001b08a30ec0050535ffe605300a0a101c8200000005b0c6f0ea4050515ffca0568b0001000e" +SPAT_MESSAGE = "001338000817a780000089680500204642b342b34802021a15a955a940181190acd0acd20100868555c555c00104342aae2aae002821a155715570" +PSM_MESSAGE = "011d0000201a0000021bd86891de75f84da101c13f042e2214141fff00022c2000270000000163b2cc7986010000" +SSM_MESSAGE = "001e120000000005e9c04071a26614c06000040ba0" +SRM_MESSAGE = "001d2130000010090bd341080d00855c6c0c6899853000a534f7c24cb29897694759b7c0" +TIM_MESSAGE = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e" +BAD_MESSAGE = "0000badc0de0000000000000000000000000000000" + +# Currently set to oim-dev environment's ODE +UDP_IP = os.getenv('DOCKER_HOST_IP') +UDP_PORT = 44990 +print("UDP target IP:", UDP_IP) +print("UDP target port:", UDP_PORT) +#print("message:", MESSAGE) + +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # UDP + +while True: + time.sleep(5) + print("sending Messages every 5 second") + sock.sendto(bytes.fromhex(BSM_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(MAP_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(SPAT_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(PSM_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(SSM_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(SRM_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(TIM_MESSAGE), (UDP_IP, UDP_PORT)) + sock.sendto(bytes.fromhex(BAD_MESSAGE), (UDP_IP, UDP_PORT)) From be3294d490361196c59a3ed2aa4c123cc722ce58 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Wed, 30 Oct 2024 07:55:37 -0600 Subject: [PATCH 041/264] Add descriptive comment to OdeTimJsonTopology --- .../src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index 5b3457efd..bf33c565b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -17,6 +17,11 @@ import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +/** + * The OdeTimJsonTopology class sets up and manages a Kafka Streams topology + * for processing TIM (Traveler Information Message) JSON data from the OdeTimJson Kafka topic. + * This class creates a K-Table that houses TMC-generated TIMs which can be queried by UUID. + **/ public class OdeTimJsonTopology { private static final Logger logger = LoggerFactory.getLogger(OdeTimJsonTopology.class); From 185fed60fdfd34b1f788c9fec6ef2f6e2ef31b7e Mon Sep 17 00:00:00 2001 From: John-Wiens Date: Wed, 30 Oct 2024 16:48:01 -0600 Subject: [PATCH 042/264] Update jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java Co-authored-by: Matt Cook --- .../main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index 392259336..9c5df009a 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -90,7 +90,8 @@ public MessageProducer( props.put("value.serializer", valueSerializerFQN); String lingerMsEnv = System.getenv("KAFKA_LINGER_MS"); - if(lingerMsEnv != null){ + if (lingerMsEnv != null && !lingerMsEnv.isEmpty()) { + int lingerMs = Integer.parseInt(lingerMsEnv); props.put("linger.ms", lingerMs); } From c328b77952fc7e77c6ad1833bdc374ffa4502c1d Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Thu, 31 Oct 2024 02:44:51 -0600 Subject: [PATCH 043/264] Moved the array support up an object for both dataframe and regions due to ODE shinanigans --- .../main/resources/schemas/schema-tim.json | 216 +++++++++--------- 1 file changed, 108 insertions(+), 108 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index b7749be6d..a22c993ad 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -355,18 +355,26 @@ "type": "string" }, "dataFrames": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ + "type": "object", + "properties": { + "TravelerDataFrame": { + "oneOf": [ + { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/J2735TravelerDataFrame" + } + ] + }, { - "$ref": "#/$defs/J2735DateFrame" + "$ref": "#/$defs/J2735TravelerDataFrame" } ] - }, - { - "$ref": "#/$defs/J2735DateFrame" } + }, + "required": [ + "TravelerDataFrame" ] }, "msgCnt": { @@ -378,96 +386,96 @@ "msgCnt" ] }, - "J2735DateFrame": { + "J2735TravelerDataFrame": { "type": "object", "properties": { - "TravelerDataFrame": { - "type": "object", - "properties": { - "notUsed": { - "type": "string" - }, - "frameType": { - "$ref": "#/$defs/J2735DF_FrameType" - }, - "msgId": { - "oneOf": [ - { - "type": "object", - "properties": { - "furtherInfoID": { - "type": "string" - } - }, - "required": [ - "furtherInfoID" - ] - }, - { - "$ref": "#/$defs/J2735DF_MsgId_RoadSignId" + "notUsed": { + "type": "string" + }, + "frameType": { + "$ref": "#/$defs/J2735DF_FrameType" + }, + "msgId": { + "oneOf": [ + { + "type": "object", + "properties": { + "furtherInfoID": { + "type": "string" } + }, + "required": [ + "furtherInfoID" ] }, - "startYear": { - "type": "string" - }, - "startTime": { - "type": "string" - }, - "durationTime": { - "type": "string" - }, - "priority": { - "type": "string" - }, - "notUsed1": { - "type": "string" - }, - "regions": { + { + "$ref": "#/$defs/J2735DF_MsgId_RoadSignId" + } + ] + }, + "startYear": { + "type": "string" + }, + "startTime": { + "type": "string" + }, + "durationTime": { + "type": "string" + }, + "priority": { + "type": "string" + }, + "notUsed1": { + "type": "string" + }, + "regions": { + "type": "object", + "properties": { + "GeographicalPath": { "oneOf": [ { "type": "array", "prefixItems": [ { - "$ref": "#/$defs/J2735DF_Regions" + "$ref": "#/$defs/J2735DF_GeographicalPath" } ] }, { - "$ref": "#/$defs/J2735DF_Regions" + "$ref": "#/$defs/J2735DF_GeographicalPath" } ] - }, - "notUsed2": { - "type": "string" - }, - "notUsed3": { - "type": "string" - }, - "content": { - "$ref": "#/$defs/J2735DF_Content" - }, - "url": { - "type": "string" } }, "required": [ - "notUsed", - "frameType", - "msgId", - "startTime", - "durationTime", - "priority", - "notUsed1", - "regions", - "notUsed2", - "notUsed3", - "content" + "GeographicalPath" ] + }, + "notUsed2": { + "type": "string" + }, + "notUsed3": { + "type": "string" + }, + "content": { + "$ref": "#/$defs/J2735DF_Content" + }, + "url": { + "type": "string" } }, "required": [ - "TravelerDataFrame" + "notUsed", + "frameType", + "msgId", + "startTime", + "durationTime", + "priority", + "notUsed1", + "regions", + "notUsed2", + "notUsed3", + "content" ] }, "J2735DF_FrameType": { @@ -544,44 +552,36 @@ "roadSignID" ] }, - "J2735DF_Regions": { + "J2735DF_GeographicalPath": { "type": "object", "properties": { - "GeographicalPath": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "id": { - "$ref": "#/$defs/J2735RoadSegmentReferenceID" - }, - "anchor": { - "$ref": "#/$defs/J2735Position3D" - }, - "laneWidth": { - "type": "string" - }, - "directionality": { - "$ref": "#/$defs/J2735DirectionOfUse" - }, - "closedPath": { - "$ref": "#/$defs/BooleanObject" - }, - "direction": { - "type": "string" - }, - "description": { - "$ref": "#/$defs/J2735DF_Regions_Description" - } - }, - "required": [ - "description" - ] + "name": { + "type": "string" + }, + "id": { + "$ref": "#/$defs/J2735RoadSegmentReferenceID" + }, + "anchor": { + "$ref": "#/$defs/J2735Position3D" + }, + "laneWidth": { + "type": "string" + }, + "directionality": { + "$ref": "#/$defs/J2735DirectionOfUse" + }, + "closedPath": { + "$ref": "#/$defs/BooleanObject" + }, + "direction": { + "type": "string" + }, + "description": { + "$ref": "#/$defs/J2735DF_Regions_Description" } }, "required": [ - "GeographicalPath" + "description" ] }, "J2735DirectionOfUse": { From 47af139eb21c14a82ae5099004d298620a32f8af Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Fri, 1 Nov 2024 14:21:42 -0600 Subject: [PATCH 044/264] Add the array support for the dataFrames and regions --- .../main/resources/schemas/schema-tim.json | 94 ++++++++++++------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index a22c993ad..7119375dc 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -355,26 +355,18 @@ "type": "string" }, "dataFrames": { - "type": "object", - "properties": { - "TravelerDataFrame": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735TravelerDataFrame" - } - ] - }, + "oneOf": [ + { + "type": "array", + "prefixItems": [ { - "$ref": "#/$defs/J2735TravelerDataFrame" + "$ref": "#/$defs/OdeTimDataFrame" } ] + }, + { + "$ref": "#/$defs/OdeTimDataFrame" } - }, - "required": [ - "TravelerDataFrame" ] }, "msgCnt": { @@ -386,6 +378,29 @@ "msgCnt" ] }, + "OdeTimDataFrame": { + "type": "object", + "properties": { + "TravelerDataFrame": { + "oneOf": [ + { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/J2735TravelerDataFrame" + } + ] + }, + { + "$ref": "#/$defs/J2735TravelerDataFrame" + } + ] + } + }, + "required": [ + "TravelerDataFrame" + ] + }, "J2735TravelerDataFrame": { "type": "object", "properties": { @@ -429,26 +444,18 @@ "type": "string" }, "regions": { - "type": "object", - "properties": { - "GeographicalPath": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735DF_GeographicalPath" - } - ] - }, + "oneOf": [ + { + "type": "array", + "prefixItems": [ { - "$ref": "#/$defs/J2735DF_GeographicalPath" + "$ref": "#/$defs/J2735DF_Regions" } ] + }, + { + "$ref": "#/$defs/J2735DF_Regions" } - }, - "required": [ - "GeographicalPath" ] }, "notUsed2": { @@ -552,6 +559,29 @@ "roadSignID" ] }, + "J2735DF_Regions": { + "type": "object", + "properties": { + "GeographicalPath": { + "oneOf": [ + { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/J2735DF_GeographicalPath" + } + ] + }, + { + "$ref": "#/$defs/J2735DF_GeographicalPath" + } + ] + } + }, + "required": [ + "GeographicalPath" + ] + }, "J2735DF_GeographicalPath": { "type": "object", "properties": { From 600ff708831b096a5deb44c9ba3c4a3bb9a638f3 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 4 Nov 2024 08:52:33 -0700 Subject: [PATCH 045/264] Supporting metadata.rsus.rsus as a list --- .../src/main/resources/schemas/schema-tim.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index 7119375dc..14ccfb46e 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -95,7 +95,19 @@ "type": "object", "properties": { "rsus": { - "$ref": "#/$defs/RequestRsus" + "oneOf": [ + { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/RequestRsus" + } + ] + }, + { + "$ref": "#/$defs/RequestRsus" + } + ] } }, "required": [ From 9c9fe70a6762e29ce8d401c9188eebce7270e857 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 4 Nov 2024 13:50:53 -0700 Subject: [PATCH 046/264] Fixed inconsistent json property annotating in Circle subclass of Asn1Object --- .../ode/plugin/j2735/timstorage/Circle.java | 87 +++++++++---------- 1 file changed, 39 insertions(+), 48 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java index c30c3133e..45bd347f8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java @@ -1,18 +1,18 @@ /******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ +* Copyright 2018 572682 +* +* Licensed under the Apache License, Version 2.0 (the "License"); you may not +* use this file except in compliance with the License. You may obtain a copy +* of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +* License for the specific language governing permissions and limitations under +* the License. +******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -22,48 +22,39 @@ @JsonPropertyOrder({ "center", "radius", "units" }) public class Circle extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private Position center; + @JsonProperty("center") + private Position center; - @JsonProperty("radius") - private String radius; + @JsonProperty("radius") + private String radius; - @JsonProperty("units") - private DistanceUnits units; + @JsonProperty("units") + private DistanceUnits units; - @JsonProperty("position") - public Position getPosition() { - return center; - } + public Position getCenter() { + return center; + } - @JsonProperty("center") - public void setPosition(Position position) { - this.center = position; - } + public void setCenter(Position center) { + this.center = center; + } - public String getRadius() { - return radius; - } + public String getRadius() { + return radius; + } - public void setRadius(String radius) { - this.radius = radius; - } + public void setRadius(String radius) { + this.radius = radius; + } - public Position getCenter() { - return center; - } + public DistanceUnits getUnits() { + return units; + } - public void setCenter(Position center) { - this.center = center; - } - - public DistanceUnits getUnits() { - return units; - } - - public void setUnits(DistanceUnits units) { - this.units = units; - } + public void setUnits(DistanceUnits units) { + this.units = units; + } } From 27c2766da0d4893bff242ed7c612b88aa770a8fb Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 4 Nov 2024 13:58:25 -0700 Subject: [PATCH 047/264] Reverted changes to whitespace in header of Circle subclass of Asn1Object --- .../ode/plugin/j2735/timstorage/Circle.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java index 45bd347f8..90c5e130e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java @@ -1,18 +1,18 @@ /******************************************************************************* -* Copyright 2018 572682 -* -* Licensed under the Apache License, Version 2.0 (the "License"); you may not -* use this file except in compliance with the License. You may obtain a copy -* of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -* License for the specific language governing permissions and limitations under -* the License. -******************************************************************************/ + * Copyright 2018 572682 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; From 827ccc04334b88885f80884cff9de8432cfc3717 Mon Sep 17 00:00:00 2001 From: Marc Wodahl Date: Tue, 5 Nov 2024 14:47:13 +0000 Subject: [PATCH 048/264] Update depositToFilteredTopic return type --- .../dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index cabc556a3..921eb2514 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -420,7 +420,7 @@ private String stripHeader(String encodedUnsignedTim) { return toReturn; } - private Void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim, ServiceRequest request) { + private void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim, ServiceRequest request) { try { String generatedBy = metadataObj.getString("recordGeneratedBy"); String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); @@ -445,6 +445,5 @@ private Void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim } catch (Exception e) { logger.error("Error while fetching recordGeneratedBy field: {}", e.getMessage()); } - return null; } } From a62ac30542344bffa29da7b70f493e108be9704e Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 5 Nov 2024 10:01:34 -0700 Subject: [PATCH 049/264] Added unit test to verify proper circle XML output from TimTransmogrifier --- .../ode/traveler/TimTransmogrifierTest.java | 577 ++++++++++-------- .../aemInputContainingCircleGeometry.xml | 1 + .../timRequestContainingCircleGeometry.json | 83 +++ 3 files changed, 402 insertions(+), 259 deletions(-) create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 9a2446f81..c9acdc0b4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -10,8 +10,14 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; import org.json.JSONObject; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -24,8 +30,7 @@ import mockit.MockUp; import mockit.Mocked; import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.model.OdeMsgMetadata; -import us.dot.its.jpo.ode.model.SerialId; +import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; import us.dot.its.jpo.ode.plugin.SNMP; import us.dot.its.jpo.ode.plugin.ServiceRequest; @@ -33,7 +38,9 @@ import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; import us.dot.its.jpo.ode.plugin.j2735.DdsGeoRegion; import us.dot.its.jpo.ode.plugin.j2735.OdeGeoRegion; +import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; import us.dot.its.jpo.ode.plugin.j2735.builders.GeoRegionBuilder; +import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; import us.dot.its.jpo.ode.plugin.j2735.timstorage.TravelerInputData; import us.dot.its.jpo.ode.traveler.TimTransmogrifier.TimTransmogrifierException; import us.dot.its.jpo.ode.util.DateTimeUtils; @@ -44,262 +51,314 @@ public class TimTransmogrifierTest { - @Mocked - OdeProperties mockOdeProperties; - - private static String schemaVersion = "7"; - - @BeforeAll - public static void setupClass() { - schemaVersion = Integer.toString(OdeProperties.OUTPUT_SCHEMA_VERSION); - } - - @Test - public void testGetRsu() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuUsername(); - result = "v3user"; - - mockOdeProperties.getRsuPassword(); - result = "password"; - } - }; - - RSU expected = new RSU("127.0.0.1", "v3user", "password", 1, 2000); - - // rsuUsername and rsuPassword are null - RSU actual1 = new RSU("127.0.0.1", null, null, 1, 2000); - TimTransmogrifier.updateRsuCreds(actual1, mockOdeProperties); - assertEquals(expected, actual1); - - // rsuUsername and rsuPassword are not-null - RSU actual2 = new RSU("127.0.0.1", "v3user", "password", 1, 2000); - TimTransmogrifier.updateRsuCreds(actual2, mockOdeProperties); - assertEquals(expected, actual2); - - // rsuUsername and rsuPassword are blank - RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); - TimTransmogrifier.updateRsuCreds(actual3, mockOdeProperties); - assertEquals(expected, actual3); - } - - @Test - public void testObfuscateRsuPassword() { - String actual = TimTransmogrifier.obfuscateRsuPassword( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); - assertEquals( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", - actual); - } - - public void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) - throws JsonUtilsException, XmlUtilsException { - JsonNode obj = JsonUtils.toObjectNode(array); - JsonNode oldObj = obj.get(arrayKey); - - JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); - String actualXml = XmlUtils.toXmlStatic(newObj); - - assertEquals(expectedXml, actualXml); - } - - @Test - public void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { - String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String singleXmlExpected = "127.0.0.3v3userpassword1100010"; - assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); - - String multi = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String multiXmlExpected = "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; - assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, multiXmlExpected); - } - - @Test - public void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); - assertNull(actualASD); - } - - @Test - public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws TimTransmogrifierException { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - inputServiceRequest.setSnmp(new SNMP()); - - try { - TimTransmogrifier.buildASD(inputServiceRequest); - fail("Expected TimTransmogrifierException"); - } catch (Exception e) { - assertTrue(e instanceof TimTransmogrifierException); - } - } - - @Test - public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws TimTransmogrifierException { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - - try { - TimTransmogrifier.buildASD(inputServiceRequest); - fail("Expected TimTransmogrifierException"); - } catch (Exception e) { - assertTrue(e instanceof TimTransmogrifierException); - } - } - - @Test - public void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException { - - SNMP inputSNMP = new SNMP(); - inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - inputServiceRequest.setSnmp(inputSNMP); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - public void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException { - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - public void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, - @Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { - - new Expectations() { - { - DateTimeUtils.now(); - result = "timeTime"; - } - }; - - new MockUp() { - @Mock - public DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { - return new DdsGeoRegion(); - } - }; - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, staticSerialId); - String expected = String.format("us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F0000000017876BA7F2030000000000331", schemaVersion); - assertEquals(expected, actualXML); - } - - @Test - public void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateTimeUtils, - @Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { - - new Expectations() { - { - DateTimeUtils.now(); - result = "timeTime"; - } - }; - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); - var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", schemaVersion); - assertEquals(expected,actualXML); - } - - @Test - public void testCreateOdeTimData() throws JsonUtilsException { - - JSONObject testObject = JsonUtils - .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); - JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); - - assertEquals( - "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", - actualOdeTimData.toString()); - } - - @Test - public void testConstructorIsPrivate() - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { - - Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - try { - constructor.newInstance(); - fail("Expected IllegalAccessException.class"); - } catch (Exception e) { - assertEquals(InvocationTargetException.class, e.getClass()); - } - } + @Mocked + OdeProperties mockOdeProperties; + + private static String schemaVersion = "7"; + + @BeforeAll + public static void setupClass() { + schemaVersion = Integer.toString(OdeProperties.OUTPUT_SCHEMA_VERSION); + } + + @Test + public void testGetRsu() throws IOException { + new Expectations() { + { + mockOdeProperties.getRsuUsername(); + result = "v3user"; + + mockOdeProperties.getRsuPassword(); + result = "password"; + } + }; + + RSU expected = new RSU("127.0.0.1", "v3user", "password", 1, 2000); + + // rsuUsername and rsuPassword are null + RSU actual1 = new RSU("127.0.0.1", null, null, 1, 2000); + TimTransmogrifier.updateRsuCreds(actual1, mockOdeProperties); + assertEquals(expected, actual1); + + // rsuUsername and rsuPassword are not-null + RSU actual2 = new RSU("127.0.0.1", "v3user", "password", 1, 2000); + TimTransmogrifier.updateRsuCreds(actual2, mockOdeProperties); + assertEquals(expected, actual2); + + // rsuUsername and rsuPassword are blank + RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); + TimTransmogrifier.updateRsuCreds(actual3, mockOdeProperties); + assertEquals(expected, actual3); + } + + @Test + public void testObfuscateRsuPassword() { + String actual = TimTransmogrifier.obfuscateRsuPassword( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); + assertEquals( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", + actual); + } + + public void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) + throws JsonUtilsException, XmlUtilsException { + JsonNode obj = JsonUtils.toObjectNode(array); + JsonNode oldObj = obj.get(arrayKey); + + JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); + String actualXml = XmlUtils.toXmlStatic(newObj); + + assertEquals(expectedXml, actualXml); + } + + @Test + public void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { + String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String singleXmlExpected = "127.0.0.3v3userpassword1100010"; + assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); + + String multi = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String multiXmlExpected = "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; + assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, multiXmlExpected); + } + + @Test + public void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); + assertNull(actualASD); + } + + @Test + public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws TimTransmogrifierException { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + inputServiceRequest.setSnmp(new SNMP()); + + try { + TimTransmogrifier.buildASD(inputServiceRequest); + fail("Expected TimTransmogrifierException"); + } catch (Exception e) { + assertTrue(e instanceof TimTransmogrifierException); + } + } + + @Test + public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws TimTransmogrifierException { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + + try { + TimTransmogrifier.buildASD(inputServiceRequest); + fail("Expected TimTransmogrifierException"); + } catch (Exception e) { + assertTrue(e instanceof TimTransmogrifierException); + } + } + + @Test + public void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) + throws TimTransmogrifierException { + + SNMP inputSNMP = new SNMP(); + inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + inputServiceRequest.setSnmp(inputSNMP); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + public void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) + throws TimTransmogrifierException { + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + public void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, + @Capturing GeoRegionBuilder capturingGeoRegionBuilder) + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { + + new Expectations() { + { + DateTimeUtils.now(); + result = "timeTime"; + } + }; + + new MockUp() { + @Mock + public DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { + return new DdsGeoRegion(); + } + }; + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, staticSerialId); + String expected = String.format("us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F0000000017876BA7F2030000000000331", schemaVersion); + assertEquals(expected, actualXML); + } + + @Test + public void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateTimeUtils, + @Capturing GeoRegionBuilder capturingGeoRegionBuilder) + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { + + new Expectations() { + { + DateTimeUtils.now(); + result = "timeTime"; + } + }; + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); + var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", schemaVersion); + assertEquals(expected,actualXML); + } + + @Test + public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { + // prepare + String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); + OdeTravelerInputData odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); + ServiceRequest request = odeTID.getRequest(); + if (request.getOde() == null) { + request.setOde(new ServiceRequest.OdeInternal()); + } + request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + timMetadata.setOdePacketID(tim.getPacketID()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + if (null != tim.getDataframes() && tim.getDataframes().length > 0) { + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = maxDurationTime > dataFrameItem.getDurationTime() ? maxDurationTime + : dataFrameItem.getDurationTime(); + try { + latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null + && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime); + } catch (ParseException e) { +// logger.error("Invalid dateTime parse: " + e); + } + } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + } + SerialId serialId = new SerialId(); + serialId.setStreamId("testStreamId"); + timMetadata.setSerialId(serialId); + timMetadata.setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.TMC); + timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + ObjectNode encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); + timMetadata.setSchemaVersion(OdeProperties.OUTPUT_SCHEMA_VERSION); + + // execute + String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); + // replace with a fixed value for comparison + actualXML = actualXML.replaceFirst(".*", "2024-11-05T16:51:14.473Z"); + + // verify + String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))); + Assertions.assertEquals(expectedXml, actualXML); + } + + @Test + public void testCreateOdeTimData() throws JsonUtilsException { + + JSONObject testObject = JsonUtils + .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); + JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); + + assertEquals( + "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", + actualOdeTimData.toString()); + } + + @Test + public void testConstructorIsPrivate() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { + + Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + try { + constructor.newInstance(); + fail("Expected IllegalAccessException.class"); + } catch (Exception e) { + assertEquals(InvocationTargetException.class, e.getClass()); + } + } } diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml new file mode 100644 index 000000000..d9de3debd --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml @@ -0,0 +1 @@ +us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPERMessageFrame3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000

411535930-104655785018240
50004868null \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json new file mode 100644 index 000000000..f10840371 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json @@ -0,0 +1,83 @@ +{ + "request": { + "rsus": [ + { + "rsuIndex": "21", + "rsuTarget": "172.0.0.1", + "rsuUsername": "username", + "rsuPassword": "password", + "rsuRetries": "3", + "rsuTimeout": "5000" + } + ], + "snmp": { + "rsuid": "83", + "msgid": "31", + "mode": "1", + "channel": "183", + "interval": "1000", + "deliverystart": "2024-09-25T10:00:00.0Z", + "deliverystop": "2024-09-30T10:00:00.0Z", + "enable": "1", + "status": "4" + } + }, + "tim": { + "msgCnt": "1", + "timeStamp": "2024-09-25T10:00:00.0Z", + "packetID": "8D442FF4020C6B1A01", + "urlB": "null", + "dataframes": [ + { + "startDateTime": "2024-09-25T10:00:00.000Z", + "durationTime": 8640, + "sspTimRights": "0", + "frameType": "advisory", + "msgId": { + "roadSignID": { + "mutcdCode": "warning", + "viewAngle": "1111111111111111", + "position": { + "latitude": "41.153593", + "longitude": "-104.655785" + } + } + }, + "priority": "5", + "sspLocationRights": "0", + "regions": [ + { + "name": "myregionname", + "anchorPosition": { + "latitude": "41.153593", + "longitude": "-104.655785" + }, + "directionality": "3", + "closedPath": "false", + "description": "geometry", + "geometry": { + "direction": "1111000011110000", + "circle": { + "center": { + "latitude": "41.153593", + "longitude": "-104.655785", + "elevation": "1824" + }, + "radius": "50", + "units": "3" + } + }, + "direction": "1111000011110000" + } + ], + "sspMsgTypes": "0", + "sspMsgContent": "0", + "content": "advisory", + "items": [ + "4868" + ], + "url": "null" + } + ] + } +} From 031d16cb1fcd9596059ca75fdafc6595e5e9ec7a Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 5 Nov 2024 11:09:50 -0700 Subject: [PATCH 050/264] Cleaned up new tim transmogrifier unit test --- .../ode/traveler/TimTransmogrifierTest.java | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index c9acdc0b4..4deaa6f02 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -288,33 +288,23 @@ public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConvers String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); OdeTravelerInputData odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); ServiceRequest request = odeTID.getRequest(); - if (request.getOde() == null) { - request.setOde(new ServiceRequest.OdeInternal()); - } + request.setOde(new ServiceRequest.OdeInternal()); request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); OdeTravelerInformationMessage tim = odeTID.getTim(); OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); timMetadata.setOdePacketID(tim.getPacketID()); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - if (null != tim.getDataframes() && tim.getDataframes().length > 0) { - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = maxDurationTime > dataFrameItem.getDurationTime() ? maxDurationTime - : dataFrameItem.getDurationTime(); - try { - latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null - && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime); - } catch (ParseException e) { -// logger.error("Invalid dateTime parse: " + e); - } - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); + latestStartDateTime = latestStartDateTime == null || latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime; } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); SerialId serialId = new SerialId(); serialId.setStreamId("testStreamId"); timMetadata.setSerialId(serialId); @@ -326,10 +316,9 @@ public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConvers // execute String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); - // replace with a fixed value for comparison - actualXML = actualXML.replaceFirst(".*", "2024-11-05T16:51:14.473Z"); // verify + actualXML = actualXML.replaceFirst(".*", "2024-11-05T16:51:14.473Z"); // replace with a fixed value for comparison String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))); Assertions.assertEquals(expectedXml, actualXML); } From e57ccb356df9ce5d9b381f8bb9d93375850ad935 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 5 Nov 2024 14:41:34 -0700 Subject: [PATCH 051/264] Added comment for new test case in TimTransmogrifierTest --- .../us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 4deaa6f02..379f2d287 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -282,6 +282,13 @@ public void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateT assertEquals(expected,actualXML); } + /** + * It should be noted that the 'prepare' section of this test largely follows the + * logic in the TimDepositController.depositTim() method. This is because the + * TimTransmogrifier.convertToXml() method is called by the TimDepositController + * and the TimDepositController is responsible for preparing the data that is + * passed to the TimTransmogrifier.convertToXml() method. + */ @Test public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { // prepare From 6c93eae9af8aa37fa5a873e950173a6010280827 Mon Sep 17 00:00:00 2001 From: John-Wiens Date: Wed, 6 Nov 2024 09:06:16 -0700 Subject: [PATCH 052/264] Removing adm/aem.properties files --- README.md | 2 -- adm.properties | 27 --------------------------- aem.properties | 27 --------------------------- 3 files changed, 56 deletions(-) delete mode 100644 adm.properties delete mode 100644 aem.properties diff --git a/README.md b/README.md index 765981547..bcb662467 100644 --- a/README.md +++ b/README.md @@ -283,8 +283,6 @@ git submodule deinit -f . && git submodule update --recursive --init Copy the following files from `jpo-ode` directory into your DOCKER_SHARED_VOLUME directory. - Copy jpo-ode/ppm.properties to ${DOCKER_SHARED_VOLUME}/config.properties. Open the newly copied `config.properties` file in a text editor and update the `metadata.broker.list=your.docker.host.ip:9092` line with your system's DOCKER_HOST_IP in place of the dummy `your.docker.host.ip` string. -- Copy jpo-ode/adm.properties to ${DOCKER_SHARED_VOLUME}/adm.properties -- Copy jpo-ode/aem.properties to ${DOCKER_SHARED_VOLUME}/aem.properties - Copy jpo-utils/sample.env to jpo-utils/.env - Fill in the variables as described in the [README](jpo-utils/README.md) diff --git a/adm.properties b/adm.properties deleted file mode 100644 index a6a0075a0..000000000 --- a/adm.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Kafka group. -group.id=0 - -# ACM operation type specification; default is decode if left out. -acm.type=decode - -# Path (relative or absolute) to the ACM error reporting XML template. -acm.error.template=/asn1_codec/config/Output.error.xml - -# Kafka topics for ASN.1 Parsing -asn1.j2735.topic.consumer=topic.Asn1DecoderInput -asn1.j2735.topic.producer=topic.Asn1DecoderOutput - -# Amount of time to wait when no message is available (milliseconds) -# This is a Kafka configuration parameter that we are using for the -# intended purpose. -asn1.j2735.consumer.timeout.ms=5000 - -# For testing purposes, use one partition. -asn1.j2735.kafka.partition=0 - -# The host ip address for the Broker. -# metadata.broker.list=localhost:9092 - -# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd -compression.type=zstd - diff --git a/aem.properties b/aem.properties deleted file mode 100644 index ce1fc0969..000000000 --- a/aem.properties +++ /dev/null @@ -1,27 +0,0 @@ -# Kafka group. -group.id=0 - -# ACM operation type specification; default is decode if left out. -acm.type=encode - -# Path (relative or absolute) to the ACM error reporting XML template. -acm.error.template=/asn1_codec/config/Output.error.xml - -# Kafka topics for ASN.1 Parsing -asn1.j2735.topic.consumer=topic.Asn1EncoderInput -asn1.j2735.topic.producer=topic.Asn1EncoderOutput - -# Amount of time to wait when no message is available (milliseconds) -# This is a Kafka configuration parameter that we are using for the -# intended purpose. -asn1.j2735.consumer.timeout.ms=5000 - -# For testing purposes, use one partition. -asn1.j2735.kafka.partition=0 - -# The host ip address for the Broker. -# metadata.broker.list=localhost:9092 - -# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd -compression.type=zstd - From c7df0d8c3b021586cd660164250148dd97ca9159 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Wed, 6 Nov 2024 16:21:56 -0700 Subject: [PATCH 053/264] Update the Tim schema test --- .../src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java index 73832b293..9a626ccff 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java @@ -27,7 +27,7 @@ public class OdeTimDataTest { @Test public void shouldValidateJson() throws Exception { // Load json schema from resource - JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V4); + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-tim.json").toURI()); final JsonNode node = (JsonNode)JsonUtils.fromJson(json, JsonNode.class); Set validationMessages = schema.validate(node); From 6abb0db6e93f89ddf7e7c0e7bf05b34daba3fd8f Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Mon, 11 Nov 2024 09:11:53 -0700 Subject: [PATCH 054/264] Extract Kafka Topics and related configurations into Spring Configuration properties (#112) * Migrate kafka configuration values to ODEKafkaProperties This is the first part of the work needed to separate the OdeProperties into multpile more manageable chunks. It introduces the usage of application.yaml and @Autowired in tests to more fully utilize the Spring framework. * remove @Component annotation and accept linter errors Adding the @Component annotation to the *Receivers caused double instantiations and port binding issues * migrate from application.properties to application.yaml and introducde host-ip config val * add make restart target for easier, faster restarts that don't require a full image rebuild * add missing getHostId test for odekafkaproperties * move odekafkaproperties to kafka package * correctly declare restart target as PHONY in Makefile * move OdeKafkaPropertiesTest to correct test package * add tests to OdePropertiesTest for hostIP and remove unused imports and variables * moved hostID from OdeKafkaProperties to AppContext to keep scope of new class small and directed * correct application.yaml's disabled-topics block * correct formatting in Asn1*JSONTest.java files and fix Sonarlint errors All swaps of argument positions in the mentioned tests are to align the function calls to the defition: assert*(expected, actual). Before this swap, the call was made in the tests like assert*(actual, expected) which has the same outcome when tests *pass* but is confusing when tests do not pass because the failure output will have the actual and expected values swapped in the message. * replace complex if-else nest with simpler switch statments in decoded data router * extract BSM properties from OdeProperties * correct application.yaml indentation for bsm block * reformat GenericReceiver * if-else to switch and pull logic out of nested if-block where possible * define topics structure in application.yaml * convert MessagePublisher to interface and implement in existing publishers * ImporterDirectoryWatcher properties and necessary refactors for related classes * Complete refactoring of UdpServicesController w/ intro of UDPReceiverProperties * add sprint.http.multipart config values to application.yaml * Add TODO for @mcook42 to update README.md with corrected instructions once OdeProperties refactor is completed * remove remaining references to kafka properties from OdeProperties * remove dead test code and add missing constructor param to ImporterDirectoryWatcherTest.java * finalize application.yaml topics structure and config classes * asn1decoder flows updated with new configuration objects * asn1encoder flows updated with new configuration objects * FileSystemStorageService refactor to use new configuration properties * delete unused BSMReceiverPropertiesTest.java * File-related controllers and watchers corrected for new configuration objects * Update TimDepositController with new topics configs * ByteArrayPublisher correct config usage * TimTransmorgrifierTest corrections * LogFileToAsn1CodecPublisherTest corrections * Revert "TimTransmorgrifierTest corrections" This reverts commit 2a27569087ce82d9e392bb1eb67ff26fcc04f7a7. * Trivial JMockit test fixes via \@Inject annotations * update test application.yaml * test application.yaml and OdeKafkaPropertiesTest correction * explicitly initialize OdeDataPublisher in OdeDataPublisherTest to avoid JMockit limitations with Set mocking * Adjust ImporterDirectoryWatcherTest.java to confirm directory creation instead of trying to run .run() It doesn't make much sense to test the scheduledExecutor when we already have a test suite for the ImporterProcessor called by the scheduled executor. JMockit doesn't play nicely (easily) with Spring configuration objects, so in the interest of time I refactored this test suite to confirm that we create the necessary directories without the use of JMockit. * OdeStringPublisherTest corrections to avoid JMockit Set mocking limitations * Replace unintentionally deleted license header in MessagePublisher * remove unnecessary comments from UdpServicesController * added missing tests for new configs in kafka package * reformatted LogFileToAsn1CodecPublisher for readability * pull RSUProperties up and refactor tests for clarity in OdePropertiesTest and TimTransmogrifierTest * remove redundant @Value annotations from OdeKafkaProperties * add missing AbstractUdpReceiverPublisher slf4j annotation * typo fixes, renames, and comment correction for LogFileToAsn1CodecPublisher and RSUProperties * remove dead/incorrect comment from TimDepositController * add slf4j annotation to ImporterProcessor * use the correct environment variable names for tim-ingest-monitoring in application.yaml * add @Import annotation to InetPacketSenderTest to ensure EventLogger is available during test runs * replace EventLogger with slf4j logger in InetPacketSenderTest * replace EventLogger with slf4j logger in InetPacketSender * move OdeTimJsonTMCFiltered topic from OdeProperties to JsonTopics after merge * OdeTimJsonTopologyTest remove unnecessary public access modifiers --- asn1_codec | 2 +- jpo-cvdp | 2 +- .../its/jpo/ode/inet/InetPacketSender.java | 12 +- .../jpo/ode/inet/InetPacketSenderTest.java | 10 +- .../wrapper/AbstractSubscriberProcessor.java | 16 +- .../its/jpo/ode/wrapper/MessageProducer.java | 2 +- .../jpo/ode/ConfigEnvironmentVariables.java | 6 - .../us/dot/its/jpo/ode/OdeProperties.java | 263 ++---- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 28 +- .../its/jpo/ode/coder/ByteArrayPublisher.java | 20 +- .../jpo/ode/coder/FileAsn1CodecPublisher.java | 18 +- .../its/jpo/ode/coder/MessagePublisher.java | 31 +- .../its/jpo/ode/coder/OdeDataPublisher.java | 22 +- .../its/jpo/ode/coder/OdeStringPublisher.java | 24 +- .../its/jpo/ode/coder/StringPublisher.java | 25 +- .../coder/stream/FileImporterProperties.java | 17 + .../stream/LogFileToAsn1CodecPublisher.java | 338 +++---- .../jpo/ode/exporter/StompStringExporter.java | 15 +- .../importer/ImporterDirectoryWatcher.java | 166 ++-- .../jpo/ode/importer/ImporterProcessor.java | 47 +- .../its/jpo/ode/kafka/Asn1CoderTopics.java | 15 + .../us/dot/its/jpo/ode/kafka/FileTopics.java | 13 + .../us/dot/its/jpo/ode/kafka/JsonTopics.java | 36 + .../its/jpo/ode/kafka/OdeKafkaProperties.java | 9 - .../us/dot/its/jpo/ode/kafka/PojoTopics.java | 27 + .../jpo/ode/kafka/RawEncodedJsonTopics.java | 18 + .../its/jpo/ode/kafka/SDXDepositorTopics.java | 12 + .../us/dot/its/jpo/ode/rsu/RSUProperties.java | 14 + .../ode/services/asn1/Asn1CommandManager.java | 296 +++--- .../services/asn1/Asn1DecodedDataRouter.java | 284 +++--- .../services/asn1/Asn1EncodedDataRouter.java | 780 +++++++-------- .../asn1/AsnCodecRouterServiceController.java | 53 +- .../AbstractAsn1DecodeMessageJSON.java | 28 +- .../asn1/message/Asn1DecodeBSMJSON.java | 30 +- .../asn1/message/Asn1DecodeMAPJSON.java | 30 +- .../asn1/message/Asn1DecodePSMJSON.java | 29 +- .../asn1/message/Asn1DecodeSPATJSON.java | 30 +- .../asn1/message/Asn1DecodeSRMJSON.java | 29 +- .../asn1/message/Asn1DecodeSSMJSON.java | 29 +- .../asn1/message/Asn1DecodeTIMJSON.java | 29 +- .../AsnCodecMessageServiceController.java | 64 +- .../ode/services/json/ToJsonConverter.java | 5 +- .../json/ToJsonServiceController.java | 28 +- .../ode/storage/FileSystemStorageService.java | 22 +- .../ode/traveler/TimDepositController.java | 540 +++++------ .../TimIngestPropertiesValidator.java | 20 + .../traveler/TimIngestTrackerProperties.java | 15 + .../jpo/ode/traveler/TimQueryController.java | 8 +- .../jpo/ode/traveler/TimTransmogrifier.java | 4 +- .../ode/udp/AbstractUdpReceiverPublisher.java | 70 +- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 75 +- .../udp/controller/UDPReceiverProperties.java | 25 + .../udp/controller/UdpServicesController.java | 58 +- .../jpo/ode/udp/generic/GenericReceiver.java | 128 ++- .../dot/its/jpo/ode/udp/map/MapReceiver.java | 46 +- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 44 +- .../its/jpo/ode/udp/spat/SpatReceiver.java | 39 +- .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 19 +- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 46 +- .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 75 +- .../jpo/ode/upload/FileUploadController.java | 153 ++- .../src/main/resources/application.yaml | 95 ++ .../us/dot/its/jpo/ode/OdePropertiesTest.java | 271 ++---- .../its/jpo/ode/OdeTimJsonTopologyTest.java | 32 +- .../jpo/ode/coder/ByteArrayPublisherTest.java | 2 +- .../jpo/ode/coder/OdeDataPublisherTest.java | 69 +- .../jpo/ode/coder/OdeStringPublisherTest.java | 48 +- .../LogFileToAsn1CodecPublisherTest.java | 704 +++++++------- .../its/jpo/ode/exporter/ExporterTest.java | 4 +- .../ode/exporter/StompStringExporterTest.java | 4 +- .../ImporterDirectoryWatcherTest.java | 127 +-- .../ImporterDirectoryWatcherTestOld.java | 136 --- .../jpo/ode/kafka/Asn1CoderTopicsTest.java | 40 + .../dot/its/jpo/ode/kafka/FileTopicsTest.java | 30 + .../dot/its/jpo/ode/kafka/JsonTopicsTest.java | 110 +++ .../dot/its/jpo/ode/kafka/PojoTopicsTest.java | 80 ++ .../ode/kafka/RawEncodedJsonTopicsTest.java | 55 ++ .../jpo/ode/kafka/SDXDepositorTopicsTest.java | 25 + .../services/asn1/Asn1CommandManagerTest.java | 4 + .../AsnCodecRouterServiceControllerTest.java | 72 +- .../asn1/message/Asn1DecodeBSMJSONTest.java | 23 +- .../asn1/message/Asn1DecodeMAPJSONTest.java | 21 +- .../asn1/message/Asn1DecodePSMJSONTest.java | 32 +- .../asn1/message/Asn1DecodeSPATJSONTest.java | 21 +- .../asn1/message/Asn1DecodeSRMJSONTest.java | 20 +- .../asn1/message/Asn1DecodeSSMJSONTest.java | 19 +- .../asn1/message/Asn1DecodeTIMJSONTest.java | 19 +- .../AsnCodecMessageServiceControllerTest.java | 14 +- .../json/ToJsonServiceControllerTest.java | 12 +- .../storage/FileSystemStorageServiceTest.java | 67 +- .../traveler/TimDepositControllerTest.java | 15 + .../TimIngestPropertiesValidatorTest.java | 42 + .../TimIngestTrackerPropertiesTest.java | 30 + .../ode/traveler/TimQueryControllerTest.java | 893 +++++++++--------- .../ode/traveler/TimTransmogrifierTest.java | 69 +- .../ode/upload/FileUploadControllerTest.java | 179 ++-- .../src/test/resources/application.yaml | 106 ++- jpo-sdw-depositor | 2 +- jpo-security-svcs | 2 +- jpo-utils | 2 +- 100 files changed, 3982 insertions(+), 3853 deletions(-) delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/FileImporterProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidator.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidatorTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java diff --git a/asn1_codec b/asn1_codec index b6c05cca8..6ce8588e7 160000 --- a/asn1_codec +++ b/asn1_codec @@ -1 +1 @@ -Subproject commit b6c05cca889bbab42bcc6b4a73c336c0b09ac930 +Subproject commit 6ce8588e77cde969fa419f1cc960c4eb05829ff1 diff --git a/jpo-cvdp b/jpo-cvdp index 4c3662ab4..23b593eee 160000 --- a/jpo-cvdp +++ b/jpo-cvdp @@ -1 +1 @@ -Subproject commit 4c3662ab416d75c88779459f8789afaffab31695 +Subproject commit 23b593eeebacd82b7f334ac926709d424c7bcc28 diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java index e084a7b61..bafa1d1d3 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java @@ -20,12 +20,14 @@ import java.net.DatagramSocket; import java.net.SocketException; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.eventlog.EventLogger; /** * Sender/Forwarder helper class for use by Forwarder, Transport, and Data Sink * that need to send packets around */ +@Slf4j public class InetPacketSender { private static final String INVALID_PARAMETERS_MSG = "Invalid Parameters. Parameters destination point and payload can not be null"; @@ -62,7 +64,7 @@ public InetPacketSender(InetPoint frwdPoint) { */ public void forward(DatagramPacket packet) throws InetPacketException { if (packet == null) { - EventLogger.logger.warn("Ignoring forward request for null packet"); + log.warn("Ignoring forward request for null packet"); return; } if (frwdPoint == null) @@ -78,7 +80,7 @@ public void forward(DatagramPacket packet) throws InetPacketException { */ public void send(DatagramPacket packet) throws InetPacketException { if (packet == null) { - EventLogger.logger.warn("Ignoring send request for null packet"); + log.warn("Ignoring send request for null packet"); return; } InetPacket p = new InetPacket(packet); @@ -101,11 +103,11 @@ public void forward(InetPoint dstPoint, byte[] payload) throws InetPacketExcepti if (dstPoint == null || payload == null) throw new InetPacketException(INVALID_PARAMETERS_MSG); if (frwdPoint == null) - EventLogger.logger.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); + log.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll())) { send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); } else { - EventLogger.logger.debug("Using direct send instead of forwarding"); + log.debug("Using direct send instead of forwarding"); send(dstPoint, payload); } } @@ -125,7 +127,7 @@ public void forward(InetPoint dstPoint, byte[] payload, boolean fromForwarder) t if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll() || fromForwarder)) { send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); } else { - EventLogger.logger.debug("Using direct send instead of forwarding"); + log.debug("Using direct send instead of forwarding"); send(dstPoint, payload); } } diff --git a/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java b/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java index 9150eceff..b2ecc8a42 100644 --- a/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java +++ b/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java @@ -31,7 +31,7 @@ import java.net.UnknownHostException; import java.util.Arrays; -import us.dot.its.jpo.ode.eventlog.EventLogger; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Disabled; @@ -40,8 +40,8 @@ import mockit.Capturing; import us.dot.its.jpo.ode.util.CodecUtils; +@Slf4j public class InetPacketSenderTest { - static final private boolean isDebugOutput = false; @@ -191,15 +191,15 @@ public void run() { socket.receive(datagramPacket); validatePacket(datagramPacket); } catch (SocketTimeoutException ex) { - EventLogger.logger.error( + log.error( String.format("Caught socket timeout exception while recieving message on port %d. Max size is %d", listenPort, DEFAULT_MAX_PACKET_SIZE), ex); } catch (SocketException ex) { - EventLogger.logger.error(String.format("Caught socket exception while recieving message on port %d. Max size is %d", + log.error(String.format("Caught socket exception while recieving message on port %d. Max size is %d", listenPort, DEFAULT_MAX_PACKET_SIZE), ex); } catch (IOException ex) { - EventLogger.logger.error( + log.error( String.format("Caught IO exception exception while recieving message on port %d. Max size is %d", listenPort, DEFAULT_MAX_PACKET_SIZE), ex); diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/AbstractSubscriberProcessor.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/AbstractSubscriberProcessor.java index 0fda858a1..24db75524 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/AbstractSubscriberProcessor.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/AbstractSubscriberProcessor.java @@ -15,12 +15,11 @@ ******************************************************************************/ package us.dot.its.jpo.ode.wrapper; +import lombok.extern.slf4j.Slf4j; + import java.util.Arrays; import java.util.concurrent.Executors; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * @author 572682 * @@ -33,9 +32,9 @@ * @param * Received Message Value Type */ +@Slf4j public abstract class AbstractSubscriberProcessor extends MessageProcessor { - private Logger logger = LoggerFactory.getLogger(this.getClass()); protected int messagesConsumed = 0; /** @@ -45,14 +44,9 @@ public abstract class AbstractSubscriberProcessor extends MessageProcessor * @param inputTopics */ public void start(MessageConsumer consumer, String... inputTopics) { - logger.info("Subscribing to {}", Arrays.asList(inputTopics).toString()); + log.info("Subscribing to {}", Arrays.asList(inputTopics)); - Executors.newSingleThreadExecutor().submit(new Runnable() { - @Override - public void run() { - consumer.subscribe(inputTopics); - } - }); + Executors.newSingleThreadExecutor().submit(() -> consumer.subscribe(inputTopics)); } @Override diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index 9c5df009a..37834d700 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -64,7 +64,7 @@ public static MessageProducer defaultStringMessageProducer( String brokers, String type, Set disabledTopics) { - return new MessageProducer( + return new MessageProducer<>( brokers, type, null, diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java deleted file mode 100644 index 9992afeb6..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/ConfigEnvironmentVariables.java +++ /dev/null @@ -1,6 +0,0 @@ -package us.dot.its.jpo.ode; - -public class ConfigEnvironmentVariables { - public static final String ODE_TIM_INGEST_MONITORING_ENABLED = "ODE_TIM_INGEST_MONITORING_ENABLED"; - public static final String ODE_TIM_INGEST_MONITORING_INTERVAL = "ODE_TIM_INGEST_MONITORING_INTERVAL"; // in seconds -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index f6f1e57c6..bc77354e4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,203 +15,94 @@ ******************************************************************************/ package us.dot.its.jpo.ode; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - import jakarta.annotation.PostConstruct; - import lombok.Data; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.info.BuildProperties; import org.springframework.context.EnvironmentAware; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; - import us.dot.its.jpo.ode.model.OdeMsgMetadata; -import us.dot.its.jpo.ode.plugin.OdePlugin; +import us.dot.its.jpo.ode.rsu.RSUProperties; @Configuration @ConfigurationProperties(prefix = "ode") @Data +@Slf4j public class OdeProperties implements EnvironmentAware { - private static final Logger logger = LoggerFactory.getLogger(OdeProperties.class); - - @Autowired - private Environment env; - - /* - * General Properties - */ - public static final int OUTPUT_SCHEMA_VERSION = 7; - private String pluginsLocations = "plugins"; - @Value("${ode.host-ip:localhost}") - private String hostIP; - - private Boolean verboseJson = false; - private int importProcessorBufferSize = OdePlugin.INPUT_STREAM_BUFFER_SIZE; - private List uploadLocations = new ArrayList<>(); - - /* - * RSU Properties - */ - private int rsuSrmSlots = 100; // number of "store and repeat message" indicies for RSU TIMs - private String rsuUsername = ""; - private String rsuPassword = ""; - - /* - * Security Services Module Properties - */ - private String securitySvcsSignatureUri; - private int securitySvcsPort = 8090; - private String securitySvcsSignatureEndpoint = "sign"; - - // File import properties - private String uploadLocationRoot = "uploads"; - private String uploadLocationObuLog = "bsmlog"; - private Integer fileWatcherPeriod = 5; // time to wait between processing inbox directory for new files - - /* - * UDP Properties - */ - private int trustRetries = 2; // if trust handshake fails, how many times to retry - private int messagesUntilTrustReestablished = 10; // renew trust session every x messages - - // BSM - private String kafkaTopicOdeBsmPojo = "topic.OdeBsmPojo"; - private String kafkaTopicOdeBsmJson = "topic.OdeBsmJson"; - private String kafkaTopicOdeBsmRxPojo = "topic.OdeBsmRxPojo"; - private String kafkaTopicOdeBsmTxPojo = "topic.OdeBsmTxPojo"; - private String kafkaTopicOdeBsmDuringEventPojo = "topic.OdeBsmDuringEventPojo"; - private String kafkaTopicFilteredOdeBsmJson = "topic.FilteredOdeBsmJson"; - private String kafkaTopicOdeRawEncodedBSMJson = "topic.OdeRawEncodedBSMJson"; - private int bsmReceiverPort = 46800; - private int bsmBufferSize = 500; - - // TIM - private String kafkaTopicOdeTimJson = "topic.OdeTimJson"; - private String kafkaTopicOdeTimJsonTMCFiltered = "topic.OdeTimJsonTMCFiltered"; - private String kafkaTopicOdeDNMsgJson = "topic.OdeDNMsgJson"; - private String kafkaTopicOdeTimRxJson = "topic.OdeTimRxJson"; - private String kafkaTopicOdeTimBroadcastPojo = "topic.OdeTimBroadcastPojo"; - private String kafkaTopicOdeTimBroadcastJson = "topic.OdeTimBroadcastJson"; - private String kafkaTopicJ2735TimBroadcastJson = "topic.J2735TimBroadcastJson"; - private String kafkaTopicFilteredOdeTimJson = "topic.FilteredOdeTimJson"; - private String kafkaTopicOdeRawEncodedTIMJson = "topic.OdeRawEncodedTIMJson"; - private int timReceiverPort = 47900; - private int timBufferSize = 500; - - //SPAT - private String kafkaTopicOdeSpatTxPojo = "topic.OdeSpatTxPojo"; - private String kafkaTopicOdeSpatPojo = "topic.OdeSpatPojo"; - private String kafkaTopicOdeSpatJson = "topic.OdeSpatJson"; - private String kafkaTopicOdeSpatRxPojo = "topic.OdeSpatRxPojo"; - private String kafkaTopicOdeSpatRxJson = "topic.OdeSpatRxJson"; - private String kafkaTopicFilteredOdeSpatJson = "topic.FilteredOdeSpatJson"; - private String kafkaTopicOdeRawEncodedSPATJson = "topic.OdeRawEncodedSPATJson"; - private int spatReceiverPort = 44910; - private int spatBufferSize = 500; - - //SSM - private String kafkaTopicOdeSsmPojo = "topic.OdeSsmPojo"; - private String kafkaTopicOdeSsmJson = "topic.OdeSsmJson"; - private String kafkaTopicOdeRawEncodedSSMJson = "topic.OdeRawEncodedSSMJson"; - private int ssmReceiverPort = 44900; - private int ssmBufferSize = 500; - - //SRM - private String kafkaTopicOdeSrmTxPojo = "topic.OdeSrmTxPojo"; - private String kafkaTopicOdeSrmJson = "topic.OdeSrmJson"; - private String kafkaTopicOdeRawEncodedSRMJson = "topic.OdeRawEncodedSRMJson"; - private int srmReceiverPort = 44930; - private int srmBufferSize = 500; - - //MAP - private String kafkaTopicOdeRawEncodedMAPJson = "topic.OdeRawEncodedMAPJson"; - private String kafkaTopicOdeMapTxPojo = "topic.OdeMapTxPojo"; - private String kafkaTopicOdeMapJson = "topic.OdeMapJson"; - private int mapReceiverPort = 44920; - private int mapBufferSize = 2048; - - // PSM - private String kafkaTopicOdeRawEncodedPSMJson = "topic.OdeRawEncodedPSMJson"; - private String kafkaTopicOdePsmTxPojo = "topic.OdePsmTxPojo"; - private String kafkaTopicOdePsmJson = "topic.OdePsmJson"; - private int psmReceiverPort = 44940; - private int psmBufferSize = 500; - - // Generic Receiver - private int genericReceiverPort = 44990; - private int genericBufferSize = 2000; - - // DriverAlerts - private String kafkaTopicDriverAlertJson = "topic.OdeDriverAlertJson"; - - // ASN.1 CODEC - private String kafkaTopicAsn1DecoderInput = "topic.Asn1DecoderInput"; - private String kafkaTopicAsn1DecoderOutput = "topic.Asn1DecoderOutput"; - private String kafkaTopicAsn1EncoderInput = "topic.Asn1EncoderInput"; - private String kafkaTopicAsn1EncoderOutput = "topic.Asn1EncoderOutput"; - - // SDX Depositor Module - private String kafkaTopicSdwDepositorInput = "topic.SDWDepositorInput"; - - //Signed Tim with expiration - private String kafkaTopicSignedOdeTimJsonExpiration = "topic.OdeTIMCertExpirationTimeJson"; - /* - * Security Properties - */ - private String caCertPath; - private String selfCertPath; - private String selfPrivateKeyReconstructionFilePath; - private String selfSigningPrivateKeyFilePath; - - private static final byte[] JPO_ODE_GROUP_ID = "jode".getBytes(); - - @Autowired - BuildProperties buildProperties; - - @PostConstruct - void initialize() { - logger.info("groupId: {}", buildProperties.getGroup()); - logger.info("artifactId: {}", buildProperties.getArtifact()); - logger.info("version: {}", buildProperties.getVersion()); - OdeMsgMetadata.setStaticSchemaVersion(OUTPUT_SCHEMA_VERSION); - - uploadLocations.add(Paths.get(uploadLocationRoot)); - - // URI for the security services /sign endpoint - if (securitySvcsSignatureUri == null) { - securitySvcsSignatureUri = "http://" + hostIP + ":" + securitySvcsPort + "/" - + securitySvcsSignatureEndpoint; - } - } - - public String getVersion() { - return buildProperties.getVersion(); - } - - public String getProperty(String key) { - return env.getProperty(key); - } - - public String getProperty(String key, String defaultValue) { - return env.getProperty(key, defaultValue); - } - - public Object getProperty(String key, int i) { - return env.getProperty(key, Integer.class, i); - } - - @Override - public void setEnvironment(Environment environment) { - env = environment; - } + @Autowired + private Environment env; + + /* + * General Properties + */ + private int outputSchemaVersion; + private String pluginsLocations; + private String hostIP; + private boolean verboseJson; + + /* + * Security Services Module Properties + */ + private String securitySvcsSignatureUri; + private int securitySvcsPort; + private String securitySvcsSignatureEndpoint; + + /* + * Security Properties + */ + private String caCertPath; + private String selfCertPath; + private String selfPrivateKeyReconstructionFilePath; + private String selfSigningPrivateKeyFilePath; + + private static final byte[] JPO_ODE_GROUP_ID = "jode".getBytes(); + + @Autowired + BuildProperties buildProperties; + + @PostConstruct + void initialize() { + log.info("groupId: {}", buildProperties.getGroup()); + log.info("artifactId: {}", buildProperties.getArtifact()); + log.info("version: {}", buildProperties.getVersion()); + OdeMsgMetadata.setStaticSchemaVersion(this.outputSchemaVersion); + + // URI for the security services /sign endpoint + if (securitySvcsSignatureUri == null) { + securitySvcsSignatureUri = "http://" + hostIP + ":" + securitySvcsPort + "/" + + securitySvcsSignatureEndpoint; + } + } + + public String getVersion() { + return buildProperties.getVersion(); + } + + public String getProperty(String key) { + return env.getProperty(key); + } + + public String getProperty(String key, String defaultValue) { + return env.getProperty(key, defaultValue); + } + + public Object getProperty(String key, int i) { + return env.getProperty(key, Integer.class, i); + } + + @Override + public void setEnvironment(Environment environment) { + env = environment; + } + + @Bean + public RSUProperties rsuProperties() { + return new RSUProperties(); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index bf33c565b..76ebb2197 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode; +import lombok.extern.slf4j.Slf4j; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.KafkaStreams; import org.apache.kafka.streams.StoreQueryParameters; @@ -9,34 +10,27 @@ import org.apache.kafka.streams.kstream.Materialized; import org.apache.kafka.streams.state.QueryableStoreTypes; import org.apache.kafka.streams.state.Stores; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import java.util.Properties; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; - /** * The OdeTimJsonTopology class sets up and manages a Kafka Streams topology * for processing TIM (Traveler Information Message) JSON data from the OdeTimJson Kafka topic. * This class creates a K-Table that houses TMC-generated TIMs which can be queried by UUID. **/ +@Slf4j public class OdeTimJsonTopology { - - private static final Logger logger = LoggerFactory.getLogger(OdeTimJsonTopology.class); + private final Properties streamsProperties = new Properties(); - private OdeProperties odeProperties = new OdeProperties(); - private OdeKafkaProperties odeKafkaProps = new OdeKafkaProperties(); static KafkaStreams streams; - public OdeTimJsonTopology(OdeProperties odeProps, OdeKafkaProperties odeKafkaProps) { - this.odeProperties = odeProps; - this.odeKafkaProps = odeKafkaProps; - if (this.odeKafkaProps.getBrokers() != null) { + public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps) { + if (odeKafkaProps.getBrokers() != null) { this.streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); - this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, this.odeKafkaProps.getBrokers()); + this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); this.streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass()); this.streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass()); @@ -45,7 +39,7 @@ public OdeTimJsonTopology(OdeProperties odeProps, OdeKafkaProperties odeKafkaPro addConfluentProperties(this.streamsProperties); } } else { - logger.error("Kafka Brokers not set in OdeProperties"); + log.error("Kafka Brokers not set in OdeProperties"); } } @@ -56,14 +50,14 @@ public void start() { if (streams == null) { streams = new KafkaStreams(buildTopology(), streamsProperties); } - logger.info("Starting Ode Tim Json Topology"); + log.info("Starting Ode Tim Json Topology"); streams.start(); } } public void stop() { if (streams != null) { - logger.info("Stopping Ode Tim Json Topology"); + log.info("Stopping Ode Tim Json Topology"); streams.close(); } } @@ -93,7 +87,7 @@ private void addConfluentProperties(Properties properties) { this.streamsProperties.put("sasl.jaas.config", auth); } else { - logger.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); + log.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); } } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java index 9683e8334..b8975125c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java @@ -15,28 +15,24 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class ByteArrayPublisher extends MessagePublisher { +@Slf4j +public class ByteArrayPublisher implements MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(ByteArrayPublisher.class); protected MessageProducer bytesProducer; - public ByteArrayPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(odeProperties, odeKafkaProperties); + public ByteArrayPublisher(OdeKafkaProperties odeKafkaProperties) { this.bytesProducer = MessageProducer.defaultByteArrayMessageProducer( - this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), - this.odeKafkaProperties.getDisabledTopics()); + odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); } - public void publish(byte[] msg, String topic) { - logger.debug("Publishing binary data to {}", topic); + public void publish(String topic, byte[] msg) { + log.debug("Publishing binary data to {}", topic); bytesProducer.send(topic, null, msg); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index 74ccd023d..c38cbcd22 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -17,18 +17,18 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; +import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import java.io.BufferedInputStream; import java.nio.file.Path; public class FileAsn1CodecPublisher { - public class FileAsn1CodecPublisherException extends Exception { + public static class FileAsn1CodecPublisherException extends Exception { private static final long serialVersionUID = 1L; @@ -40,14 +40,14 @@ public FileAsn1CodecPublisherException(String string, Exception e) { private static final Logger logger = LoggerFactory.getLogger(FileAsn1CodecPublisher.class); - private LogFileToAsn1CodecPublisher codecPublisher; - - @Autowired - public FileAsn1CodecPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + private final LogFileToAsn1CodecPublisher codecPublisher; - StringPublisher messagePub = new StringPublisher(odeProperties, odeKafkaProperties); + public FileAsn1CodecPublisher(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, RawEncodedJsonTopics rawEncodedJsonTopics) { + StringPublisher messagePub = new StringPublisher(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); - this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub); + this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub, jsonTopics, rawEncodedJsonTopics); } public void publishFile(Path filePath, BufferedInputStream fileInputStream, ImporterFileType fileType) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java index 5e47848b0..b49d96485 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/MessagePublisher.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,27 +15,6 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import lombok.Getter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; - -public abstract class MessagePublisher { - - private final Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Getter - protected OdeKafkaProperties odeKafkaProperties; - // TODO(Matt): remove once all kafka properties are migrated to ODEKafkaProperties and the delegates - @Getter - protected OdeProperties odeProperties; - - public MessagePublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - this.odeProperties = odeProperties; - this.odeKafkaProperties = odeKafkaProperties; - logger.info("Using Brokers: {} of Type: {}", this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType()); - } - +public interface MessagePublisher { + void publish(String topic, T message); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java index d586f0606..ed80e1d27 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java @@ -15,30 +15,30 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeObject; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class OdeDataPublisher extends MessagePublisher { +import java.util.Set; + +@Slf4j +public class OdeDataPublisher implements MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer objectProducer; - public OdeDataPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, String serializer) { - super(odeProperties, odeKafkaProperties); - this.objectProducer = new MessageProducer<>(this.odeKafkaProperties.getBrokers(), - this.odeKafkaProperties.getProducerType(), + public OdeDataPublisher(String producerType, String brokers, Set disabledTopics, String serializer) { + this.objectProducer = new MessageProducer<>(brokers, + producerType, null, serializer, - this.odeKafkaProperties.getDisabledTopics()); + disabledTopics); } - public void publish(OdeData msg, String topic) { - logger.debug("Publishing to {}: {}", topic, msg); + public void publish(String topic, OdeData msg) { + log.debug("Publishing to {}: {}", topic, msg); objectProducer.send(topic, null, msg); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java index 11362a08e..c11e2446a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeStringPublisher.java @@ -15,30 +15,28 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class OdeStringPublisher extends MessagePublisher { +import java.util.Set; + +@Slf4j +public class OdeStringPublisher implements MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(OdeDataPublisher.class); protected MessageProducer stringProducer; - public OdeStringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(odeProperties, odeKafkaProperties); + public OdeStringPublisher(String brokers, String producerType, Set disabledTopics) { this.stringProducer = MessageProducer.defaultStringMessageProducer( - this.odeKafkaProperties.getBrokers(), - this.odeKafkaProperties.getProducerType(), - this.odeKafkaProperties.getDisabledTopics()); + brokers, + producerType, + disabledTopics); } - public void publish(OdeData msg, String topic) { - logger.debug("Publishing to {}: {}", topic, msg); + public void publish(String topic, OdeData msg) { + log.debug("Publishing to {}: {}", topic, msg); stringProducer.send(topic, null, msg.toJson()); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java index 089d829aa..57cc8d50c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/StringPublisher.java @@ -15,27 +15,26 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class StringPublisher extends MessagePublisher { +import java.util.Set; + +@Slf4j +public class StringPublisher implements MessagePublisher { - private static final Logger logger = LoggerFactory.getLogger(StringPublisher.class); protected MessageProducer stringProducer; - public StringPublisher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(odeProperties, odeKafkaProperties); + public StringPublisher(String broker, String producerType, Set disabledTopics) { this.stringProducer = MessageProducer.defaultStringMessageProducer( - this.odeKafkaProperties.getBrokers(), this.odeKafkaProperties.getProducerType(), - this.odeKafkaProperties.getDisabledTopics()); - + broker, + producerType, + disabledTopics + ); } - public void publish(String msg, String topic) { - logger.debug("Publishing String data to {}", topic); + public void publish(String topic, String msg) { + log.debug("Publishing String data to {}", topic); stringProducer.send(topic, null, msg); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/FileImporterProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/FileImporterProperties.java new file mode 100644 index 000000000..03855ebae --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/FileImporterProperties.java @@ -0,0 +1,17 @@ +package us.dot.its.jpo.ode.coder.stream; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.file-importer") +@Data +public class FileImporterProperties { + private int bufferSize; + private String backupDir; + private String failedDir; + private int timePeriod; + private String uploadLocationRoot; + private String obuLogUploadLocation; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java index 075815da5..1f6bda2fc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,194 +15,160 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder.stream; -import java.io.BufferedInputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.core.JsonProcessingException; - +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; -import us.dot.its.jpo.ode.importer.parser.BsmLogFileParser; -import us.dot.its.jpo.ode.importer.parser.DriverAlertFileParser; +import us.dot.its.jpo.ode.importer.parser.*; import us.dot.its.jpo.ode.importer.parser.FileParser.ParserStatus; -import us.dot.its.jpo.ode.importer.parser.LogFileParser; -import us.dot.its.jpo.ode.importer.parser.RxMsgFileParser; -import us.dot.its.jpo.ode.importer.parser.SpatLogFileParser; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeBsmMetadata; -import us.dot.its.jpo.ode.model.OdeData; -import us.dot.its.jpo.ode.model.OdeDriverAlertData; -import us.dot.its.jpo.ode.model.OdeDriverAlertPayload; -import us.dot.its.jpo.ode.model.OdeLogMetadata; -import us.dot.its.jpo.ode.model.OdeMsgPayload; -import us.dot.its.jpo.ode.model.OdeSpatMetadata; -import us.dot.its.jpo.ode.model.RxSource; -import us.dot.its.jpo.ode.model.SerialId; -import us.dot.its.jpo.ode.util.JsonUtils; -import us.dot.its.jpo.ode.util.XmlUtils; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.uper.UperUtil; +import us.dot.its.jpo.ode.util.JsonUtils; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +@Slf4j public class LogFileToAsn1CodecPublisher implements Asn1CodecPublisher { - public static class LogFileToAsn1CodecPublisherException extends Exception { - - private static final long serialVersionUID = 1L; - - public LogFileToAsn1CodecPublisherException(String string, Exception e) { - super(string, e); - } - - } - - protected static final Logger logger = LoggerFactory.getLogger(LogFileToAsn1CodecPublisher.class); - - protected StringPublisher publisher; - protected LogFileParser fileParser; - protected SerialId serialId; - - public LogFileToAsn1CodecPublisher(StringPublisher dataPub) { - this.publisher = dataPub; - this.serialId = new SerialId(); - } - - public List publish(BufferedInputStream bis, String fileName, ImporterFileType fileType) - throws LogFileToAsn1CodecPublisherException { - XmlUtils xmlUtils = new XmlUtils(); - ParserStatus status; - - List dataList = new ArrayList<>(); - if (fileType == ImporterFileType.LOG_FILE) { - fileParser = LogFileParser.factory(fileName); - - do { - try { - status = fileParser.parseFile(bis, fileName); - if (status == ParserStatus.COMPLETE) { - addDataToList(dataList); - } else if (status == ParserStatus.EOF) { - publishList(xmlUtils, dataList); - } else if (status == ParserStatus.INIT) { - logger.error("Failed to parse the header bytes."); - } else { - logger.error("Failed to decode ASN.1 data"); - } - bis = removeNextNewLineCharacter(bis); - } catch (Exception e) { - throw new LogFileToAsn1CodecPublisherException("Error parsing or publishing data.", e); - } - } while (status == ParserStatus.COMPLETE); - } - - return dataList; - } - - private void addDataToList(List dataList) { - - OdeData odeData; - - OdeMsgPayload payload; - OdeLogMetadata metadata; - if (isDriverAlertRecord()) { - payload = new OdeDriverAlertPayload(((DriverAlertFileParser) fileParser).getAlert()); - metadata = new OdeLogMetadata(payload); - odeData = new OdeDriverAlertData(metadata, payload); - } else if (isBsmRecord()) { - payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); - metadata = new OdeBsmMetadata(payload); - odeData = new OdeAsn1Data(metadata, payload); - } else if (isSpatRecord()) { - payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); - metadata = new OdeSpatMetadata(payload); - odeData = new OdeAsn1Data(metadata, payload); - } else { - payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); - metadata = new OdeLogMetadata(payload); - odeData = new OdeAsn1Data(metadata, payload); - } - fileParser.updateMetadata(metadata); - - dataList.add(odeData); - } - - public boolean isDriverAlertRecord() { - return fileParser instanceof DriverAlertFileParser; - } - - public boolean isBsmRecord() { - return fileParser instanceof BsmLogFileParser || (fileParser instanceof RxMsgFileParser - && ((RxMsgFileParser) fileParser).getRxSource() == RxSource.RV); - } - - public boolean isSpatRecord() { - return fileParser instanceof SpatLogFileParser; - } - - private void publishList(XmlUtils xmlUtils, List dataList) throws JsonProcessingException { - serialId.setBundleSize(dataList.size()); - - for (OdeData odeData : dataList) { - OdeLogMetadata msgMetadata = (OdeLogMetadata) odeData.getMetadata(); - OdeMsgPayload msgPayload = (OdeMsgPayload) odeData.getPayload(); - msgMetadata.setSerialId(serialId); - - if (isDriverAlertRecord()) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicDriverAlertJson()); - } else if (isBsmRecord()) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); - } else if (isSpatRecord()) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); - } else { - // Determine the message type (MAP, TIM, SSM, SRM, or PSM) - String messageType = UperUtil.determineMessageType(msgPayload); - if (messageType.equals("MAP")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); - } else if(messageType.equals("SPAT")){ - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); - } else if (messageType.equals("TIM")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); - } else if (messageType.equals("BSM")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); - } else if (messageType.equals("SSM")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSSMJson()); - } else if (messageType.equals("SRM")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSRMJson()); - } else if (messageType.equals("PSM")) { - publisher.publish(JsonUtils.toJson(odeData, false), - publisher.getOdeProperties().getKafkaTopicOdeRawEncodedPSMJson()); - } - } - - serialId.increment(); - } - } - - // This method will check if the next character is a newline character (0x0A in hex or 10 in converted decimal) - // or if the next character does not contain a newline character it will put that character back into the buffered input stream - public BufferedInputStream removeNextNewLineCharacter(BufferedInputStream bis) { - try { - bis.mark(1); - int nextByte = bis.read(); - if (nextByte != 10) { // If the next byte is not a newline - bis.reset(); // Reset the stream back to the most recent mark - } - } catch (IOException e) { - e.printStackTrace(); - } - return bis; - } + public static class LogFileToAsn1CodecPublisherException extends Exception { + + private static final long serialVersionUID = 1L; + + public LogFileToAsn1CodecPublisherException(String string, Exception e) { + super(string, e); + } + + } + + private final RawEncodedJsonTopics rawEncodedJsonTopics; + private final JsonTopics jsonTopics; + protected StringPublisher publisher; + protected LogFileParser fileParser; + protected SerialId serialId; + + public LogFileToAsn1CodecPublisher(StringPublisher stringPublisher, JsonTopics jsonTopics, RawEncodedJsonTopics rawEncodedJsonTopics) { + this.jsonTopics = jsonTopics; + this.rawEncodedJsonTopics = rawEncodedJsonTopics; + this.publisher = stringPublisher; + this.serialId = new SerialId(); + } + + public List publish(BufferedInputStream inputStream, String fileName, ImporterFileType fileType) + throws LogFileToAsn1CodecPublisherException { + ParserStatus status; + + List dataList = new ArrayList<>(); + if (fileType == ImporterFileType.LOG_FILE) { + fileParser = LogFileParser.factory(fileName); + + do { + try { + status = fileParser.parseFile(inputStream, fileName); + switch (status) { + case ParserStatus.COMPLETE -> addDataToList(dataList); + case ParserStatus.EOF -> publishList(dataList); + case ParserStatus.INIT -> log.error("Failed to parse the header bytes."); + default -> log.error("Failed to decode ASN.1 data"); + } + inputStream = removeNextNewLineCharacter(inputStream); + } catch (Exception e) { + throw new LogFileToAsn1CodecPublisherException("Error parsing or publishing data.", e); + } + } while (status == ParserStatus.COMPLETE); + } + + return dataList; + } + + private void addDataToList(List dataList) { + + OdeData odeData; + + OdeMsgPayload payload; + OdeLogMetadata metadata; + if (isDriverAlertRecord()) { + payload = new OdeDriverAlertPayload(((DriverAlertFileParser) fileParser).getAlert()); + metadata = new OdeLogMetadata(payload); + odeData = new OdeDriverAlertData(metadata, payload); + } else if (isBsmRecord()) { + payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); + metadata = new OdeBsmMetadata(payload); + odeData = new OdeAsn1Data(metadata, payload); + } else if (isSpatRecord()) { + payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); + metadata = new OdeSpatMetadata(payload); + odeData = new OdeAsn1Data(metadata, payload); + } else { + payload = new OdeAsn1Payload(fileParser.getPayloadParser().getPayload()); + metadata = new OdeLogMetadata(payload); + odeData = new OdeAsn1Data(metadata, payload); + } + fileParser.updateMetadata(metadata); + + dataList.add(odeData); + } + + public boolean isDriverAlertRecord() { + return fileParser instanceof DriverAlertFileParser; + } + + public boolean isBsmRecord() { + return fileParser instanceof BsmLogFileParser || (fileParser instanceof RxMsgFileParser + && ((RxMsgFileParser) fileParser).getRxSource() == RxSource.RV); + } + + public boolean isSpatRecord() { + return fileParser instanceof SpatLogFileParser; + } + + private void publishList(List dataList) { + serialId.setBundleSize(dataList.size()); + + for (OdeData odeData : dataList) { + OdeLogMetadata msgMetadata = (OdeLogMetadata) odeData.getMetadata(); + OdeMsgPayload msgPayload = odeData.getPayload(); + msgMetadata.setSerialId(serialId); + + if (isDriverAlertRecord()) { + publisher.publish(jsonTopics.getDriverAlert(), JsonUtils.toJson(odeData, false)); + } else if (isBsmRecord()) { + publisher.publish(rawEncodedJsonTopics.getBsm(), JsonUtils.toJson(odeData, false)); + } else if (isSpatRecord()) { + publisher.publish(rawEncodedJsonTopics.getSpat(), JsonUtils.toJson(odeData, false)); + } else { + String messageType = UperUtil.determineMessageType(msgPayload); + switch (messageType) { + case "MAP" -> publisher.publish(rawEncodedJsonTopics.getMap(), JsonUtils.toJson(odeData, false)); + case "SPAT" -> publisher.publish(rawEncodedJsonTopics.getSpat(), JsonUtils.toJson(odeData, false)); + case "TIM" -> publisher.publish(rawEncodedJsonTopics.getTim(), JsonUtils.toJson(odeData, false)); + case "BSM" -> publisher.publish(rawEncodedJsonTopics.getBsm(), JsonUtils.toJson(odeData, false)); + case "SSM" -> publisher.publish(rawEncodedJsonTopics.getSsm(), JsonUtils.toJson(odeData, false)); + case "SRM" -> publisher.publish(rawEncodedJsonTopics.getSrm(), JsonUtils.toJson(odeData, false)); + case "PSM" -> publisher.publish(rawEncodedJsonTopics.getPsm(), JsonUtils.toJson(odeData, false)); + default -> log.warn("Unknown message type: {}", messageType); + } + } + + serialId.increment(); + } + } + + // This method will check if the next character is a newline character (0x0A in hex or 10 in converted decimal) + // or if the next character does not contain a newline character it will put that character back into the buffered input stream + public BufferedInputStream removeNextNewLineCharacter(BufferedInputStream bis) { + try { + bis.mark(1); + int nextByte = bis.read(); + if (nextByte != 10) { // If the next byte is not a newline + bis.reset(); // Reset the stream back to the most recent mark + } + } catch (IOException e) { + log.error("Error removing next newline character: ", e); + } + return bis; + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java index a7fa3c011..ba4eb04bd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/exporter/StompStringExporter.java @@ -17,7 +17,6 @@ import org.springframework.messaging.simp.SimpMessagingTemplate; import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /** @@ -25,24 +24,24 @@ */ public class StompStringExporter extends Exporter{ - private OdeKafkaProperties odeKafkaProperties; - private SimpMessagingTemplate template; - private String odeTopic; + private final SimpMessagingTemplate template; + private final String odeTopic; + private final String brokers; public StompStringExporter( - OdeKafkaProperties odeKafkaProperties, String stompTopic, SimpMessagingTemplate template, - String odeTopic) { + String odeTopic, + String brokers) { super(stompTopic); - this.odeKafkaProperties = odeKafkaProperties; + this.brokers = brokers; this.template = template; this.odeTopic = odeTopic; } @Override protected void subscribe() { - setConsumer(MessageConsumer.defaultStringMessageConsumer(odeKafkaProperties.getBrokers(), + setConsumer(MessageConsumer.defaultStringMessageConsumer(this.brokers, AppContext.getInstance().getHostId() + this.getClass().getSimpleName(), new StompStringMessageDistributor(template, getTopic()))); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java index 225e8824a..13c87f0c4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,88 +15,96 @@ ******************************************************************************/ package us.dot.its.jpo.ode.importer; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; + import java.io.IOException; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; - +@Slf4j public class ImporterDirectoryWatcher implements Runnable { - - public enum ImporterFileType { - LOG_FILE, JSON_FILE - } - - private static final Logger logger = LoggerFactory.getLogger(ImporterDirectoryWatcher.class); - - private boolean watching; - - private ImporterProcessor importerProcessor; - - private Path inbox; - private Path backup; - private Path failed; - - private ScheduledExecutorService executor; - - private Integer timePeriod; - - public ImporterDirectoryWatcher(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, Path dir, Path backupDir, Path failureDir, ImporterFileType fileType, Integer timePeriod) { - this.inbox = dir; - this.backup = backupDir; - this.failed = failureDir; - this.watching = true; - this.timePeriod = timePeriod; - - try { - OdeFileUtils.createDirectoryRecursively(inbox); - String msg = "Created directory {}"; - logger.debug(msg, inbox); - OdeFileUtils.createDirectoryRecursively(failed); - logger.debug(msg, failed); - OdeFileUtils.createDirectoryRecursively(backup); - logger.debug(msg, backup); - } catch (IOException e) { - logger.error("Error creating directory: " + inbox, e); - } - - this.importerProcessor = new ImporterProcessor(odeProperties, odeKafkaProperties, fileType); - - executor = Executors.newScheduledThreadPool(1); - } - - @Override - public void run() { - - logger.info("Processing inbox directory {} every {} seconds.", inbox, timePeriod); - - // ODE-646: the old method of watching the directory used file - // event notifications and was unreliable for large quantities of files - // Watch directory for file events - executor.scheduleWithFixedDelay(() -> importerProcessor.processDirectory(inbox, backup, failed), - 0, timePeriod, TimeUnit.SECONDS); - - try { - // This line will only execute in the event that .scheduleWithFixedDelay() throws an error - executor.awaitTermination(timePeriod, TimeUnit.SECONDS); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - logger.error("Directory watcher polling loop interrupted!", e); - } - } - - public boolean isWatching() { - return watching; - } - - public void setWatching(boolean watching) { - this.watching = watching; - } + public enum ImporterFileType { + LOG_FILE, JSON_FILE + } + + @Setter + @Getter + private boolean watching; + + private final ImporterProcessor importerProcessor; + private final FileImporterProperties props; + private final ScheduledExecutorService executor; + private final Path inboxPath; + private final Path backupPath; + private final Path failuresPath; + + public ImporterDirectoryWatcher(FileImporterProperties fileImporterProperties, + OdeKafkaProperties odeKafkaProperties, + JsonTopics jsonTopics, + ImporterFileType fileType, + RawEncodedJsonTopics rawEncodedJsonTopics) { + this.props = fileImporterProperties; + this.watching = true; + + this.inboxPath = Paths.get(fileImporterProperties.getUploadLocationRoot(), fileImporterProperties.getObuLogUploadLocation()); + log.debug("UPLOADER - BSM log file upload directory: {}", inboxPath); + + this.failuresPath = Paths.get(fileImporterProperties.getUploadLocationRoot(), fileImporterProperties.getFailedDir()); + log.debug("UPLOADER - Failure directory: {}", failuresPath); + + this.backupPath = Paths.get(fileImporterProperties.getUploadLocationRoot(), fileImporterProperties.getBackupDir()); + log.debug("UPLOADER - Backup directory: {}", backupPath); + + try { + String msg = "Created directory {}"; + + OdeFileUtils.createDirectoryRecursively(inboxPath); + log.debug(msg, inboxPath); + + OdeFileUtils.createDirectoryRecursively(failuresPath); + log.debug(msg, failuresPath); + + OdeFileUtils.createDirectoryRecursively(backupPath); + log.debug(msg, backupPath); + } catch (IOException e) { + log.error("Error creating directory", e); + } + + this.importerProcessor = new ImporterProcessor(new FileAsn1CodecPublisher(odeKafkaProperties, jsonTopics, rawEncodedJsonTopics), + fileType, + fileImporterProperties.getBufferSize()); + + executor = Executors.newScheduledThreadPool(1); + } + + @Override + public void run() { + + log.info("Processing inbox directory {} every {} seconds.", inboxPath, props.getTimePeriod()); + + // ODE-646: the old method of watching the directory used file + // event notifications and was unreliable for large quantities of files + // Watch directory for file events + executor.scheduleWithFixedDelay(() -> importerProcessor.processDirectory(inboxPath, backupPath, failuresPath), + 0, props.getTimePeriod(), TimeUnit.SECONDS); + + try { + // This line will only execute in the event that .scheduleWithFixedDelay() throws an error + executor.awaitTermination(props.getTimePeriod(), TimeUnit.SECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.error("Directory watcher polling loop interrupted!", e); + } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java index 34a00af58..dcdd79a07 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterProcessor.java @@ -26,28 +26,25 @@ import java.util.zip.GZIPInputStream; import java.util.zip.ZipInputStream; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher.FileAsn1CodecPublisherException; import us.dot.its.jpo.ode.eventlog.EventLogger; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; +@Slf4j public class ImporterProcessor { - private static final Logger logger = LoggerFactory.getLogger(ImporterProcessor.class); - private FileAsn1CodecPublisher codecPublisher; - private OdeProperties odeProperties; - private ImporterFileType fileType; - private Pattern gZipPattern = Pattern.compile("application/.*gzip"); - private Pattern zipPattern = Pattern.compile("application/.*zip.*"); + private final int bufferSize; + private final FileAsn1CodecPublisher codecPublisher; + private final ImporterFileType fileType; + private final Pattern gZipPattern = Pattern.compile("application/.*gzip"); + private final Pattern zipPattern = Pattern.compile("application/.*zip.*"); - public ImporterProcessor(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, ImporterFileType fileType) { - this.codecPublisher = new FileAsn1CodecPublisher(odeProperties, odeKafkaProperties); - this.odeProperties = odeProperties; + public ImporterProcessor(FileAsn1CodecPublisher publisher, ImporterFileType fileType, int bufferSize) { + this.codecPublisher = publisher; + this.bufferSize = bufferSize; this.fileType = fileType; } @@ -60,14 +57,14 @@ public int processDirectory(Path dir, Path backupDir, Path failureDir) { if (entry.toFile().isDirectory()) { processDirectory(entry, backupDir, failureDir); } else { - logger.debug("Found a file to process: {}", entry.getFileName()); + log.debug("Found a file to process: {}", entry.getFileName()); processAndBackupFile(entry, backupDir, failureDir); count++; } } } catch (Exception e) { - logger.error("Error processing files.", e); + log.error("Error processing files.", e); } return count; } @@ -83,24 +80,24 @@ public void processAndBackupFile(Path filePath, Path backupDir, Path failureDir) inputStream = new FileInputStream(filePath.toFile()); String probeContentType = Files.probeContentType(filePath); if ((probeContentType != null && gZipPattern.matcher(probeContentType).matches()) || filePath.toString().toLowerCase().endsWith("gz")) { - logger.info("Treating as gzip file"); + log.info("Treating as gzip file"); inputStream = new GZIPInputStream(inputStream); bis = publishFile(filePath, inputStream); } else if ((probeContentType != null && zipPattern.matcher(probeContentType).matches()) || filePath.toString().endsWith("zip")) { - logger.info("Treating as zip file"); + log.info("Treating as zip file"); inputStream = new ZipInputStream(inputStream); ZipInputStream zis = (ZipInputStream)inputStream; while (zis.getNextEntry() != null) { bis = publishFile(filePath, inputStream); } } else { - logger.info("Treating as unknown file"); + log.info("Treating as unknown file"); bis = publishFile(filePath, inputStream); } } catch (Exception e) { success = false; - logger.error("Failed to open or process file: " + filePath, e); - EventLogger.logger.error("Failed to open or process file: " + filePath, e); + log.error("Failed to open or process file: {}", filePath, e); + EventLogger.logger.error("Failed to open or process file: {}", filePath, e); } finally { try { if (bis != null) { @@ -110,29 +107,29 @@ public void processAndBackupFile(Path filePath, Path backupDir, Path failureDir) inputStream.close(); } } catch (IOException e) { - logger.error("Failed to close file stream: {}", e); + log.error("Failed to close file stream:", e); } } try { if (success) { OdeFileUtils.backupFile(filePath, backupDir); - logger.info("File moved to backup: {}", backupDir); + log.info("File moved to backup: {}", backupDir); EventLogger.logger.info("File moved to backup: {}", backupDir); } else { OdeFileUtils.moveFile(filePath, failureDir); - logger.info("File moved to failure directory: {}", failureDir); + log.info("File moved to failure directory: {}", failureDir); EventLogger.logger.info("File moved to failure directory: {}", failureDir); } } catch (IOException e) { - logger.error("Unable to backup file: " + filePath, e); + log.error("Unable to backup file: {}", filePath, e); } } private BufferedInputStream publishFile(Path filePath, InputStream inputStream) throws FileAsn1CodecPublisherException { BufferedInputStream bis; - bis = new BufferedInputStream(inputStream, odeProperties.getImportProcessorBufferSize()); + bis = new BufferedInputStream(inputStream, this.bufferSize); codecPublisher.publishFile(filePath, bis, fileType); return bis; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java new file mode 100644 index 000000000..d2d614f2a --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java @@ -0,0 +1,15 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties("ode.kafka.topics.asn1") +@Data +public class Asn1CoderTopics { + private String decoderInput; + private String decoderOutput; + private String encoderInput; + private String encoderOutput; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java new file mode 100644 index 000000000..531e35100 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java @@ -0,0 +1,13 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.topics.file") +@Data +public class FileTopics { + private String filteredOutput; + private String unfilteredOutput; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java new file mode 100644 index 000000000..a6f7cca0d --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java @@ -0,0 +1,36 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.topics.json") +@Data +public class JsonTopics { + private String bsm; + private String map; + private String psm; + private String spat; + private String srm; + private String ssm; + private String tim; + + private String driverAlert; + + private String timBroadcast; + + private String bsmFiltered; + private String spatFiltered; + private String timFiltered; + private String timTmcFiltered; + + private String timCertExpiration; + + private String dnMessage; + + private String rxTim; + private String rxSpat; + + private String j2735TimBroadcast; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java index dcec01e11..0a3081a52 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java @@ -1,9 +1,6 @@ package us.dot.its.jpo.ode.kafka; import lombok.Data; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; @@ -13,13 +10,7 @@ @ConfigurationProperties(prefix = "ode.kafka") @Data public class OdeKafkaProperties { - - private static final Logger logger = LoggerFactory.getLogger(OdeKafkaProperties.class); - - @Value("${ode.kafka.brokers:localhost:9092}") private String brokers; - @Value("${ode.kafka.producer-type:sync}") private String producerType; - @Value("${ode.kafka.disabled-topics:}") private Set disabledTopics; } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java new file mode 100644 index 000000000..52e2da854 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.topics.pojo") +@Data +public class PojoTopics { + private String bsm; + private String spat; + private String ssm; + + private String timBroadcast; + + private String bsmDuringEvent; + + private String rxBsm; + private String rxSpat; + + private String txBsm; + private String txMap; + private String txPsm; + private String txSpat; + private String txSrm; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java new file mode 100644 index 000000000..cd421da2e --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java @@ -0,0 +1,18 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.topics.raw-encoded-json") +@Data +public class RawEncodedJsonTopics { + private String bsm; + private String map; + private String psm; + private String spat; + private String srm; + private String ssm; + private String tim; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java new file mode 100644 index 000000000..8312d65f1 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java @@ -0,0 +1,12 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.topics.sdx-depositor") +@Data +public class SDXDepositorTopics { + private String input; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java new file mode 100644 index 000000000..b50640282 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java @@ -0,0 +1,14 @@ +package us.dot.its.jpo.ode.rsu; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +@ConfigurationProperties(prefix = "ode.rsu") +public class RSUProperties { + private int srmSlots; // number of "store and repeat message" indices for RSU TIMs + private String username; + private String password; +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index c4fa2a8a4..54781150d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,25 +15,19 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; -import java.text.ParseException; -import java.util.HashMap; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; - -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsdPayload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; @@ -51,194 +45,164 @@ import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class Asn1CommandManager { - - public static final String ADVISORY_SITUATION_DATA_STRING = "AdvisorySituationData"; - private static final Logger logger = LoggerFactory.getLogger(Asn1CommandManager.class); - - public static class Asn1CommandManagerException extends Exception { - - private static final long serialVersionUID = 1L; - - public Asn1CommandManagerException(String string) { - super(string); - } - - public Asn1CommandManagerException(String msg, Exception e) { - super(msg, e); - } - - } - - private String signatureUri; - private OdeProperties odeProperties; - - private MessageProducer stringMessageProducer; - - private String depositTopic; - private RsuDepositor rsuDepositor; - - public Asn1CommandManager(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - - this.odeProperties = odeProperties; - - this.signatureUri = odeProperties.getSecuritySvcsSignatureUri(); - - try { - this.rsuDepositor = new RsuDepositor(odeProperties); - this.rsuDepositor.start(); - this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.setDepositTopic(odeProperties.getKafkaTopicSdwDepositorInput()); - } catch (Exception e) { - String msg = "Error starting SDW depositor"; - EventLogger.logger.error(msg, e); - logger.error(msg, e); - } - - } - - public void depositToSdw(String depositObj) throws Asn1CommandManagerException { - stringMessageProducer.send(this.getDepositTopic(), null, depositObj); - logger.info("Published message to SDW deposit topic"); - EventLogger.logger.info("Published message to SDW deposit topic"); - logger.debug("Message deposited: {}", depositObj); - EventLogger.logger.debug("Message deposited: {}", depositObj); - } - - public void sendToRsus(ServiceRequest request, String encodedMsg) { - - rsuDepositor.deposit(request, encodedMsg); - return; - } +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; - public String sendForSignature(String message) { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); +@Slf4j +public class Asn1CommandManager { - HttpEntity entity = new HttpEntity<>(JsonUtils.jsonKeyValue("message", message), headers); + public static final String ADVISORY_SITUATION_DATA_STRING = "AdvisorySituationData"; - RestTemplate template = new RestTemplate(); + public static class Asn1CommandManagerException extends Exception { + + private static final long serialVersionUID = 1L; - logger.info("Sending data to security services module at {} to be signed", signatureUri); - logger.debug("Data to be signed: {}", entity); + public Asn1CommandManagerException(String string) { + super(string); + } - ResponseEntity respEntity = template.postForEntity(signatureUri, entity, String.class); + public Asn1CommandManagerException(String msg, Exception e) { + super(msg, e); + } - logger.info("Security services module response: {}", respEntity); + } - return respEntity.getBody(); - } + private final String signatureUri; - public String sendForSignature(String message, int sigValidityOverride) { - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - Map map = new HashMap<>(); - map.put("message", message); - map.put("sigValidityOverride", Integer.toString(sigValidityOverride)); + private MessageProducer stringMessageProducer; - HttpEntity> entity = new HttpEntity<>(map, headers); - RestTemplate template = new RestTemplate(); + private String depositTopic; + private RsuDepositor rsuDepositor; - logger.info("Sending data to security services module with validity override at {} to be signed", - signatureUri); - logger.debug("Data to be signed: {}", entity); + public Asn1CommandManager(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, SDXDepositorTopics sdxDepositorTopics) { + this.signatureUri = odeProperties.getSecuritySvcsSignatureUri(); - ResponseEntity respEntity = template.postForEntity(signatureUri, entity, String.class); + try { + this.rsuDepositor = new RsuDepositor(odeProperties); + this.rsuDepositor.start(); + this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.depositTopic = sdxDepositorTopics.getInput(); + } catch (Exception e) { + String msg = "Error starting SDW depositor"; + EventLogger.logger.error(msg, e); + log.error(msg, e); + } + } - logger.debug("Security services module response: {}", respEntity); + public void depositToSdw(String depositObj) throws Asn1CommandManagerException { + stringMessageProducer.send(this.depositTopic, null, depositObj); + log.info("Published message to SDW deposit topic {}", this.depositTopic); + EventLogger.logger.info("Published message to SDW deposit topic"); + log.debug("Message deposited: {}", depositObj); + EventLogger.logger.debug("Message deposited: {}", depositObj); + } - return respEntity.getBody(); - } + public void sendToRsus(ServiceRequest request, String encodedMsg) { + rsuDepositor.deposit(request, encodedMsg); + } - public String packageSignedTimIntoAsd(ServiceRequest request, String signedMsg) { + public String sendForSignature(String message, int sigValidityOverride) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + Map map = new HashMap<>(); + map.put("message", message); + map.put("sigValidityOverride", Integer.toString(sigValidityOverride)); - SDW sdw = request.getSdw(); - SNMP snmp = request.getSnmp(); - DdsAdvisorySituationData asd = null; + HttpEntity> entity = new HttpEntity<>(map, headers); + RestTemplate template = new RestTemplate(); - byte sendToRsu = request.getRsus() != null ? DdsAdvisorySituationData.RSU : DdsAdvisorySituationData.NONE; - byte distroType = (byte) (DdsAdvisorySituationData.IP | sendToRsu); - // - String outputXml = null; - try { - if (null != snmp) { + log.info("Sending data to security services module with validity override at {} to be signed", + signatureUri); + log.debug("Data to be signed: {}", entity); - asd = new DdsAdvisorySituationData() - .setAsdmDetails(snmp.getDeliverystart(), snmp.getDeliverystop(), distroType, null) - .setServiceRegion(GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion())).setTimeToLive(sdw.getTtl()) - .setGroupID(sdw.getGroupID()).setRecordID(sdw.getRecordId()); - } else { - asd = new DdsAdvisorySituationData() - .setAsdmDetails(sdw.getDeliverystart(), sdw.getDeliverystop(), distroType, null) - .setServiceRegion(GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion())).setTimeToLive(sdw.getTtl()) - .setGroupID(sdw.getGroupID()).setRecordID(sdw.getRecordId()); - } + ResponseEntity respEntity = template.postForEntity(signatureUri, entity, String.class); - OdeMsgPayload payload = null; + log.debug("Security services module response: {}", respEntity); - ObjectNode dataBodyObj = JsonUtils.newNode(); - ObjectNode asdObj = JsonUtils.toObjectNode(asd.toJson()); - ObjectNode admDetailsObj = (ObjectNode) asdObj.findValue("asdmDetails"); - admDetailsObj.remove("advisoryMessage"); - admDetailsObj.put("advisoryMessage", signedMsg); + return respEntity.getBody(); + } - dataBodyObj.set(ADVISORY_SITUATION_DATA_STRING, asdObj); + public String packageSignedTimIntoAsd(ServiceRequest request, String signedMsg) { - payload = new OdeAsdPayload(asd); + SDW sdw = request.getSdw(); + SNMP snmp = request.getSnmp(); + DdsAdvisorySituationData asd = null; - ObjectNode payloadObj = JsonUtils.toObjectNode(payload.toJson()); - payloadObj.set(AppContext.DATA_STRING, dataBodyObj); + byte sendToRsu = request.getRsus() != null ? DdsAdvisorySituationData.RSU : DdsAdvisorySituationData.NONE; + byte distroType = (byte) (DdsAdvisorySituationData.IP | sendToRsu); + // + String outputXml = null; + try { + if (null != snmp) { - OdeMsgMetadata metadata = new OdeMsgMetadata(payload); - ObjectNode metaObject = JsonUtils.toObjectNode(metadata.toJson()); + asd = new DdsAdvisorySituationData() + .setAsdmDetails(snmp.getDeliverystart(), snmp.getDeliverystop(), distroType, null) + .setServiceRegion(GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion())).setTimeToLive(sdw.getTtl()) + .setGroupID(sdw.getGroupID()).setRecordID(sdw.getRecordId()); + } else { + asd = new DdsAdvisorySituationData() + .setAsdmDetails(sdw.getDeliverystart(), sdw.getDeliverystop(), distroType, null) + .setServiceRegion(GeoRegionBuilder.ddsGeoRegion(sdw.getServiceRegion())).setTimeToLive(sdw.getTtl()) + .setGroupID(sdw.getGroupID()).setRecordID(sdw.getRecordId()); + } - ObjectNode requestObj = JsonUtils.toObjectNode(JsonUtils.toJson(request, false)); + OdeMsgPayload payload = null; - requestObj.remove("tim"); + ObjectNode dataBodyObj = JsonUtils.newNode(); + ObjectNode asdObj = JsonUtils.toObjectNode(asd.toJson()); + ObjectNode admDetailsObj = (ObjectNode) asdObj.findValue("asdmDetails"); + admDetailsObj.remove("advisoryMessage"); + admDetailsObj.put("advisoryMessage", signedMsg); - metaObject.set("request", requestObj); + dataBodyObj.set(ADVISORY_SITUATION_DATA_STRING, asdObj); - ArrayNode encodings = buildEncodings(); - ObjectNode enc = XmlUtils.createEmbeddedJsonArrayForXmlConversion(AppContext.ENCODINGS_STRING, encodings); - metaObject.set(AppContext.ENCODINGS_STRING, enc); + payload = new OdeAsdPayload(asd); - ObjectNode message = JsonUtils.newNode(); - message.set(AppContext.METADATA_STRING, metaObject); - message.set(AppContext.PAYLOAD_STRING, payloadObj); + ObjectNode payloadObj = JsonUtils.toObjectNode(payload.toJson()); + payloadObj.set(AppContext.DATA_STRING, dataBodyObj); - ObjectNode root = JsonUtils.newNode(); - root.set(AppContext.ODE_ASN1_DATA, message); + OdeMsgMetadata metadata = new OdeMsgMetadata(payload); + ObjectNode metaObject = JsonUtils.toObjectNode(metadata.toJson()); - outputXml = XmlUtils.toXmlStatic(root); + ObjectNode requestObj = JsonUtils.toObjectNode(JsonUtils.toJson(request, false)); - // remove the surrounding - outputXml = outputXml.replace("", ""); - outputXml = outputXml.replace("", ""); + requestObj.remove("tim"); - } catch (ParseException | JsonUtilsException | XmlUtilsException e) { - logger.error("Parsing exception thrown while populating ASD structure: {}", e); - } + metaObject.set("request", requestObj); + + ArrayNode encodings = buildEncodings(); + ObjectNode enc = XmlUtils.createEmbeddedJsonArrayForXmlConversion(AppContext.ENCODINGS_STRING, encodings); + metaObject.set(AppContext.ENCODINGS_STRING, enc); + + ObjectNode message = JsonUtils.newNode(); + message.set(AppContext.METADATA_STRING, metaObject); + message.set(AppContext.PAYLOAD_STRING, payloadObj); + + ObjectNode root = JsonUtils.newNode(); + root.set(AppContext.ODE_ASN1_DATA, message); - logger.debug("Fully crafted ASD to be encoded: {}", outputXml); + outputXml = XmlUtils.toXmlStatic(root); - return outputXml; - } + // remove the surrounding + outputXml = outputXml.replace("", ""); + outputXml = outputXml.replace("", ""); - public static ArrayNode buildEncodings() throws JsonUtilsException { - ArrayNode encodings = JsonUtils.newArrayNode(); - encodings.add(TimTransmogrifier.buildEncodingNode(ADVISORY_SITUATION_DATA_STRING, ADVISORY_SITUATION_DATA_STRING, - EncodingRule.UPER)); - return encodings; - } + } catch (ParseException | JsonUtilsException | XmlUtilsException e) { + log.error("Parsing exception thrown while populating ASD structure: ", e); + } - public String getDepositTopic() { - return depositTopic; - } + log.debug("Fully crafted ASD to be encoded: {}", outputXml); - public void setDepositTopic(String depositTopic) { - this.depositTopic = depositTopic; - } + return outputXml; + } + public static ArrayNode buildEncodings() throws JsonUtilsException { + ArrayNode encodings = JsonUtils.newArrayNode(); + encodings.add(TimTransmogrifier.buildEncodingNode(ADVISORY_SITUATION_DATA_STRING, ADVISORY_SITUATION_DATA_STRING, + EncodingRule.UPER)); + return encodings; + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index 37d9e563d..5461612df 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,19 +15,13 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; +import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSpatDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSsmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSrmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdePsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.*; import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; @@ -38,129 +32,155 @@ import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeBsmSerializer; +@Slf4j public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor { - private Logger logger = LoggerFactory.getLogger(this.getClass()); + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; + private final MessageProducer bsmProducer; + private final MessageProducer timProducer; + private final MessageProducer spatProducer; + private final MessageProducer mapProducer; + private final MessageProducer ssmProducer; + private final MessageProducer srmProducer; + private final MessageProducer psmProducer; + + public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics pojoTopics, JsonTopics jsonTopics) { + super(); + + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + null, + OdeBsmSerializer.class.getName(), + odeKafkaProperties.getDisabledTopics()); + this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + } + + @Override + public Object process(String consumedData) { + try { + JSONObject consumed = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); + J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( + consumed.getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING) + .getJSONObject("MessageFrame") + .getInt("messageId") + ); + + RecordType recordType = RecordType + .valueOf(consumed.getJSONObject(AppContext.METADATA_STRING).getString("recordType")); + + switch (messageId) { + case BasicSafetyMessage -> routeBSM(consumedData, recordType); + case TravelerInformation -> routeTIM(consumed, recordType); + case SPATMessage -> routeSPAT(consumedData, recordType); + case MAPMessage -> routeMAP(consumedData, recordType); + case SSMMessage -> routeSSM(consumedData, recordType); + case SRMMessage -> routeSRM(consumedData, recordType); + case PersonalSafetyMessage -> routePSM(consumedData, recordType); + case null, default -> log.warn("Unknown message type: {}", messageId); + } + } catch (Exception e) { + log.error("Failed to route received data: {}", consumedData, e); + } + return null; + } + + private void routePSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumedData).toString(); + if (recordType == RecordType.psmTx) { + psmProducer.send(pojoTopics.getTxPsm(), getRecord().key(), odePsmData); + } + // Send all PSMs also to OdePsmJson + psmProducer.send(jsonTopics.getPsm(), getRecord().key(), odePsmData); + log.debug("Submitted to PSM Pojo topic {}", jsonTopics.getPsm()); + } + + private void routeSRM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumedData).toString(); + if (recordType == RecordType.srmTx) { + srmProducer.send(pojoTopics.getTxSrm(), getRecord().key(), odeSrmData); + } + // Send all SRMs also to OdeSrmJson + srmProducer.send(jsonTopics.getSrm(), getRecord().key(), odeSrmData); + log.debug("Submitted to SRM Pojo topic {}", jsonTopics.getSrm()); + } - private OdeProperties odeProperties; - private MessageProducer bsmProducer; - private MessageProducer timProducer; - private MessageProducer spatProducer; - private MessageProducer mapProducer; - private MessageProducer ssmProducer; - private MessageProducer srmProducer; - private MessageProducer psmProducer; + private void routeSSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData).toString(); + if (recordType == RecordType.ssmTx) { + ssmProducer.send(pojoTopics.getSsm(), getRecord().key(), odeSsmData); + } + // Send all SSMs also to OdeSsmJson + ssmProducer.send(jsonTopics.getSsm(), getRecord().key(), odeSsmData); + log.debug("Submitted to SSM Pojo topic {}", jsonTopics.getSsm()); + } - public Asn1DecodedDataRouter(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - super(); - this.odeProperties = odeProps; - this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - null, - OdeBsmSerializer.class.getName(), - odeKafkaProperties.getDisabledTopics()); - this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); - } + private void routeMAP(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(consumedData).toString(); + if (recordType == RecordType.mapTx) { + mapProducer.send(pojoTopics.getTxMap(), getRecord().key(), odeMapData); + } + // Send all Map also to OdeMapJson + mapProducer.send(jsonTopics.getMap(), getRecord().key(), odeMapData); + log.debug("Submitted to MAP Pojo topic {}", jsonTopics.getMap()); + } - @Override - public Object process(String consumedData) { - try { - JSONObject consumed = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); - int messageId = consumed.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING) - .getJSONObject("MessageFrame").getInt("messageId"); + private void routeSPAT(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); + switch (recordType) { + case dnMsg -> spatProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeSpatData); + case rxMsg -> spatProducer.send(jsonTopics.getRxSpat(), getRecord().key(), odeSpatData); + case spatTx -> spatProducer.send(pojoTopics.getTxSpat(), getRecord().key(), odeSpatData); + default -> log.trace("Consumed SPAT data with record type: {}", recordType); + } + // Send all SPATs also to OdeSpatJson + spatProducer.send(jsonTopics.getSpat(), getRecord().key(), odeSpatData); + log.debug("Submitted to SPAT Pojo topic {}", jsonTopics.getSpat()); + } - RecordType recordType = RecordType - .valueOf(consumed.getJSONObject(AppContext.METADATA_STRING).getString("recordType")); + private void routeTIM(JSONObject consumed, RecordType recordType) { + String odeTimData = TimTransmogrifier.createOdeTimData(consumed).toString(); + switch (recordType) { + case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); + case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); + default -> log.trace("Consumed TIM data with record type: {}", recordType); + } + // Send all TIMs also to OdeTimJson + timProducer.send(jsonTopics.getTim(), getRecord().key(), odeTimData); + log.debug("Submitted to TIM Pojo topic: {}", jsonTopics.getTim()); + } - if (messageId == J2735DSRCmsgID.BasicSafetyMessage.getMsgID()) { - // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the - // "recordType" - OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumedData); - if (recordType == RecordType.bsmLogDuringEvent) { - bsmProducer.send(odeProperties.getKafkaTopicOdeBsmDuringEventPojo(), getRecord().key(), odeBsmData); - } else if (recordType == RecordType.rxMsg) { - bsmProducer.send(odeProperties.getKafkaTopicOdeBsmRxPojo(), getRecord().key(), odeBsmData); - } else if (recordType == RecordType.bsmTx) { - bsmProducer.send(odeProperties.getKafkaTopicOdeBsmTxPojo(), getRecord().key(), odeBsmData); - } - // Send all BSMs also to OdeBsmPojo - bsmProducer.send(odeProperties.getKafkaTopicOdeBsmPojo(), getRecord().key(), odeBsmData); - logger.debug("Submitted to BSM Pojo topic"); - } else if (messageId == J2735DSRCmsgID.TravelerInformation.getMsgID()) { - String odeTimData = TimTransmogrifier.createOdeTimData(consumed).toString(); - if (recordType == RecordType.dnMsg) { - timProducer.send(odeProperties.getKafkaTopicOdeDNMsgJson(), getRecord().key(), odeTimData); - } else if (recordType == RecordType.rxMsg) { - timProducer.send(odeProperties.getKafkaTopicOdeTimRxJson(), getRecord().key(), odeTimData); - } - // Send all TIMs also to OdeTimJson - timProducer.send(odeProperties.getKafkaTopicOdeTimJson(), getRecord().key(), odeTimData); - logger.debug("Submitted to TIM Pojo topic"); - } else if (messageId == J2735DSRCmsgID.SPATMessage.getMsgID()) { - String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); - if (recordType == RecordType.dnMsg) { - spatProducer.send(odeProperties.getKafkaTopicOdeDNMsgJson(), getRecord().key(), odeSpatData); - } else if (recordType == RecordType.rxMsg) { - spatProducer.send(odeProperties.getKafkaTopicOdeSpatRxJson(), getRecord().key(), odeSpatData); - } else if (recordType == RecordType.spatTx) { - spatProducer.send(odeProperties.getKafkaTopicOdeSpatTxPojo(), getRecord().key(), odeSpatData); - } - // Send all SPATs also to OdeSpatJson - spatProducer.send(odeProperties.getKafkaTopicOdeSpatJson(), getRecord().key(), odeSpatData); - logger.debug("Submitted to SPAT Pojo topic"); - } else if (messageId == J2735DSRCmsgID.MAPMessage.getMsgID()) { - String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(consumedData).toString(); - if (recordType == RecordType.mapTx) { - mapProducer.send(odeProperties.getKafkaTopicOdeMapTxPojo(), getRecord().key(), odeMapData); - } - // Send all Map also to OdeMapJson - mapProducer.send(odeProperties.getKafkaTopicOdeMapJson(), getRecord().key(), odeMapData); - logger.debug("Submitted to MAP Pojo topic"); - } else if (messageId == J2735DSRCmsgID.SSMMessage.getMsgID()) { - String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData).toString(); - if (recordType == RecordType.ssmTx) { - ssmProducer.send(odeProperties.getKafkaTopicOdeSsmPojo(), getRecord().key(), odeSsmData); - } - // Send all SSMs also to OdeSsmJson - ssmProducer.send(odeProperties.getKafkaTopicOdeSsmJson(), getRecord().key(), odeSsmData); - logger.debug("Submitted to SSM Pojo topic"); - } else if (messageId == J2735DSRCmsgID.SRMMessage.getMsgID()) { - String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumedData).toString(); - if (recordType == RecordType.srmTx) { - srmProducer.send(odeProperties.getKafkaTopicOdeSrmTxPojo(), getRecord().key(), odeSrmData); - } - // Send all SRMs also to OdeSrmJson - srmProducer.send(odeProperties.getKafkaTopicOdeSrmJson(), getRecord().key(), odeSrmData); - logger.debug("Submitted to SRM Pojo topic"); - } else if (messageId == J2735DSRCmsgID.PersonalSafetyMessage.getMsgID()) { - String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumedData).toString(); - if (recordType == RecordType.psmTx) { - psmProducer.send(odeProperties.getKafkaTopicOdePsmTxPojo(), getRecord().key(), odePsmData); - } - // Send all PSMs also to OdePsmJson - psmProducer.send(odeProperties.getKafkaTopicOdePsmJson(), getRecord().key(), odePsmData); - logger.debug("Submitted to PSM Pojo topic"); - } - } catch (Exception e) { - logger.error("Failed to route received data: " + consumedData, e); - } - return null; - } + private void routeBSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the "recordType" + OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumedData); + switch (recordType) { + case bsmLogDuringEvent -> bsmProducer.send(pojoTopics.getBsmDuringEvent(), getRecord().key(), odeBsmData); + case rxMsg -> bsmProducer.send(pojoTopics.getRxBsm(), getRecord().key(), odeBsmData); + case bsmTx -> bsmProducer.send(pojoTopics.getTxBsm(), getRecord().key(), odeBsmData); + default -> log.trace("Consumed BSM data with record type: {}", recordType); + } + // Send all BSMs also to OdeBsmPojo + bsmProducer.send(pojoTopics.getBsm(), getRecord().key(), odeBsmData); + log.debug("Submitted to BSM Pojo topic {}", pojoTopics.getBsm()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 921eb2514..076cf3778 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,21 +15,18 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; - +import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.OdeTimJsonTopology; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; @@ -41,409 +38,412 @@ import us.dot.its.jpo.ode.wrapper.AbstractSubscriberProcessor; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class Asn1EncodedDataRouter extends AbstractSubscriberProcessor { - - private static final String BYTES = "bytes"; - - private static final String MESSAGE_FRAME = "MessageFrame"; - - private static final String ERROR_ON_SDX_DEPOSIT = "Error on SDX deposit."; - - public static class Asn1EncodedDataRouterException extends Exception { - - private static final long serialVersionUID = 1L; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; - public Asn1EncodedDataRouterException(String string) { - super(string); - } +@Slf4j +public class Asn1EncodedDataRouter extends AbstractSubscriberProcessor { - } + private static final String BYTES = "bytes"; + private static final String MESSAGE_FRAME = "MessageFrame"; + private static final String ERROR_ON_SDX_DEPOSIT = "Error on SDX deposit."; + + public static class Asn1EncodedDataRouterException extends Exception { + private static final long serialVersionUID = 1L; + + public Asn1EncodedDataRouterException(String string) { + super(string); + } + } + + private final OdeProperties odeProperties; + private final Asn1CoderTopics asn1CoderTopics; + private final JsonTopics jsonTopics; + + private final MessageProducer stringMsgProducer; + private final OdeTimJsonTopology odeTimJsonTopology; + private final Asn1CommandManager asn1CommandManager; + private final boolean dataSigningEnabledRSU; + private final boolean dataSigningEnabledSDW; + + public Asn1EncodedDataRouter(OdeProperties odeProperties, + OdeKafkaProperties odeKafkaProperties, + Asn1CoderTopics asn1CoderTopics, + JsonTopics jsonTopics, + SDXDepositorTopics sdxDepositorTopics) { + super(); + + this.odeProperties = odeProperties; + this.asn1CoderTopics = asn1CoderTopics; + this.jsonTopics = jsonTopics; + + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), + odeKafkaProperties.getDisabledTopics()); + + this.asn1CommandManager = new Asn1CommandManager(odeProperties, odeKafkaProperties, sdxDepositorTopics); + + this.dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() + ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) + : false; + this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() + ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) + : true; + + odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties); + if (!odeTimJsonTopology.isRunning()) { + odeTimJsonTopology.start(); + } + + } + + @Override + public Object process(String consumedData) { + try { + log.debug("Consumed: {}", consumedData); + JSONObject consumedObj = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); + + /* + * When receiving the 'rsus' in xml, since there is only one 'rsu' and + * there is no construct for array in xml, the rsus does not translate + * to an array of 1 element. The following workaround, resolves this + * issue. + */ + JSONObject metadata = consumedObj.getJSONObject(AppContext.METADATA_STRING); + + if (metadata.has(TimTransmogrifier.REQUEST_STRING)) { + JSONObject request = metadata.getJSONObject(TimTransmogrifier.REQUEST_STRING); + if (request.has(TimTransmogrifier.RSUS_STRING)) { + Object rsus = request.get(TimTransmogrifier.RSUS_STRING); + if (rsus instanceof JSONObject) { + JSONObject rsusIn = (JSONObject) request.get(TimTransmogrifier.RSUS_STRING); + if (rsusIn.has(TimTransmogrifier.RSUS_STRING)) { + Object rsu = rsusIn.get(TimTransmogrifier.RSUS_STRING); + JSONArray rsusOut = new JSONArray(); + if (rsu instanceof JSONArray) { + log.debug("Multiple RSUs exist in the request: {}", request); + JSONArray rsusInArray = (JSONArray) rsu; + for (int i = 0; i < rsusInArray.length(); i++) { + rsusOut.put(rsusInArray.get(i)); + } + request.put(TimTransmogrifier.RSUS_STRING, rsusOut); + } else if (rsu instanceof JSONObject) { + log.debug("Single RSU exists in the request: {}", request); + rsusOut.put(rsu); + request.put(TimTransmogrifier.RSUS_STRING, rsusOut); + } else { + log.debug("No RSUs exist in the request: {}", request); + request.remove(TimTransmogrifier.RSUS_STRING); + } + } + } + } - private Logger logger = LoggerFactory.getLogger(this.getClass()); + // Convert JSON to POJO + ServiceRequest servicerequest = getServicerequest(consumedObj); - private OdeProperties odeProperties; - private MessageProducer stringMsgProducer; - private static OdeTimJsonTopology odeTimJsonTopology = null; - private Asn1CommandManager asn1CommandManager; - private boolean dataSigningEnabledRSU; - private boolean dataSigningEnabledSDW; + processEncodedTim(servicerequest, consumedObj); + } else { + throw new Asn1EncodedDataRouterException("Invalid or missing '" + + TimTransmogrifier.REQUEST_STRING + "' object in the encoder response"); + } + } catch (Exception e) { + String msg = "Error in processing received message from ASN.1 Encoder module: " + consumedData; + if (log.isDebugEnabled()) { + // print error message and stack trace + EventLogger.logger.error(msg, e); + log.error(msg, e); + } else { + // print error message only + EventLogger.logger.error(msg); + log.error(msg); + } + } + return null; + } + + public ServiceRequest getServicerequest(JSONObject consumedObj) { + String sr = consumedObj.getJSONObject(AppContext.METADATA_STRING).getJSONObject(TimTransmogrifier.REQUEST_STRING).toString(); + log.debug("ServiceRequest: {}", sr); + + // Convert JSON to POJO + ServiceRequest serviceRequest = null; + try { + serviceRequest = (ServiceRequest) JsonUtils.fromJson(sr, ServiceRequest.class); + + } catch (Exception e) { + String errMsg = "Malformed JSON."; + EventLogger.logger.error(errMsg, e); + log.error(errMsg, e); + } + + return serviceRequest; + } + + public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { + + JSONObject dataObj = consumedObj.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING); + JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); + + // CASE 1: no SDW in metadata (SNMP deposit only) + // - sign MF + // - send to RSU + // CASE 2: SDW in metadata but no ASD in body (send back for another + // encoding) + // - sign MF + // - send to RSU + // - craft ASD object + // - publish back to encoder stream + // CASE 3: If SDW in metadata and ASD in body (double encoding complete) + // - send to SDX + + if (!dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { + log.debug("Unsigned message received"); + // We don't have ASD, therefore it must be just a MessageFrame that needs to be signed + // No support for unsecured MessageFrame only payload. + // Cases 1 & 2 + // Sign and send to RSUs + + JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); + + String hexEncodedTim = mfObj.getString(BYTES); + log.debug("Encoded message - phase 1: {}", hexEncodedTim); + //use Asnc1 library to decode the encoded tim returned from ASNC1; another class two blockers: decode the tim and decode the message-sign + + // Case 1: SNMP-deposit + if (dataSigningEnabledRSU && request.getRsus() != null) { + hexEncodedTim = signTIM(hexEncodedTim, consumedObj); + } else { + // if header is present, strip it + if (isHeaderPresent(hexEncodedTim)) { + String header = hexEncodedTim.substring(0, hexEncodedTim.indexOf("001F") + 4); + log.debug("Stripping header from unsigned message: {}", header); + hexEncodedTim = stripHeader(hexEncodedTim); + mfObj.remove(BYTES); + mfObj.put(BYTES, hexEncodedTim); + dataObj.remove(MESSAGE_FRAME); + dataObj.put(MESSAGE_FRAME, mfObj); + consumedObj.remove(AppContext.PAYLOAD_STRING); + consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); + } + } - public Asn1EncodedDataRouter(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(); + if (null != request.getSnmp() && null != request.getRsus() && null != hexEncodedTim) { + log.info("Sending message to RSUs..."); + asn1CommandManager.sendToRsus(request, hexEncodedTim); + } - this.odeProperties = odeProperties; + hexEncodedTim = mfObj.getString(BYTES); - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), - odeKafkaProperties.getDisabledTopics()); + // Case 2: SDX-deposit + if (dataSigningEnabledSDW && request.getSdw() != null) { + hexEncodedTim = signTIM(hexEncodedTim, consumedObj); + } - this.asn1CommandManager = new Asn1CommandManager(odeProperties, odeKafkaProperties); + // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated + depositToFilteredTopic(metadataObj, hexEncodedTim); + if (request.getSdw() != null) { + // Case 2 only - this.dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) - : false; - this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) - : true; + log.debug("Publishing message for round 2 encoding!"); + String xmlizedMessage = asn1CommandManager.packageSignedTimIntoAsd(request, hexEncodedTim); - // Initialize and start the OdeTimJsonTopology if it is not already running - if (odeTimJsonTopology == null) { - odeTimJsonTopology = new OdeTimJsonTopology(odeProperties, odeKafkaProperties); - if (!odeTimJsonTopology.isRunning()) { - odeTimJsonTopology.start(); - } - } - } - - @Override - public Object process(String consumedData) { - try { - logger.debug("Consumed: {}", consumedData); - JSONObject consumedObj = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); - - /* - * When receiving the 'rsus' in xml, since there is only one 'rsu' and - * there is no construct for array in xml, the rsus does not translate - * to an array of 1 element. The following workaround, resolves this - * issue. - */ - JSONObject metadata = consumedObj.getJSONObject(AppContext.METADATA_STRING); - - if (metadata.has(TimTransmogrifier.REQUEST_STRING)) { - JSONObject request = metadata.getJSONObject(TimTransmogrifier.REQUEST_STRING); - if (request.has(TimTransmogrifier.RSUS_STRING)) { - Object rsus = request.get(TimTransmogrifier.RSUS_STRING); - if (rsus instanceof JSONObject) { - JSONObject rsusIn = (JSONObject) request.get(TimTransmogrifier.RSUS_STRING); - if (rsusIn.has(TimTransmogrifier.RSUS_STRING)) { - Object rsu = rsusIn.get(TimTransmogrifier.RSUS_STRING); - JSONArray rsusOut = new JSONArray(); - if (rsu instanceof JSONArray) { - logger.debug("Multiple RSUs exist in the request: {}", request); - JSONArray rsusInArray = (JSONArray) rsu; - for (int i = 0; i < rsusInArray.length(); i++) { - rsusOut.put(rsusInArray.get(i)); - } - request.put(TimTransmogrifier.RSUS_STRING, rsusOut); - } else if (rsu instanceof JSONObject) { - logger.debug("Single RSU exists in the request: {}", request); - rsusOut.put(rsu); - request.put(TimTransmogrifier.RSUS_STRING, rsusOut); - } else { - logger.debug("No RSUs exist in the request: {}", request); - request.remove(TimTransmogrifier.RSUS_STRING); - } - } - } + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlizedMessage); } - // Convert JSON to POJO - ServiceRequest servicerequest = getServicerequest(consumedObj); - - processEncodedTim(servicerequest, consumedObj); - } else { - throw new Asn1EncodedDataRouterException("Invalid or missing '" - + TimTransmogrifier.REQUEST_STRING + "' object in the encoder response"); - } - } catch (Exception e) { - String msg = "Error in processing received message from ASN.1 Encoder module: " + consumedData; - if (logger.isDebugEnabled()) { - // print error message and stack trace - EventLogger.logger.error(msg, e); - logger.error(msg, e); - } - else { - // print error message only - EventLogger.logger.error(msg); - logger.error(msg); - } - } - return null; - } - - public ServiceRequest getServicerequest(JSONObject consumedObj) { - String sr = consumedObj.getJSONObject(AppContext.METADATA_STRING).getJSONObject(TimTransmogrifier.REQUEST_STRING).toString(); - logger.debug("ServiceRequest: {}", sr); - - // Convert JSON to POJO - ServiceRequest serviceRequest = null; - try { - serviceRequest = (ServiceRequest) JsonUtils.fromJson(sr, ServiceRequest.class); - - } catch (Exception e) { - String errMsg = "Malformed JSON."; - EventLogger.logger.error(errMsg, e); - logger.error(errMsg, e); - } - - return serviceRequest; - } - - public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { - - JSONObject dataObj = consumedObj.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING); - JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); - - // CASE 1: no SDW in metadata (SNMP deposit only) - // - sign MF - // - send to RSU - // CASE 2: SDW in metadata but no ASD in body (send back for another - // encoding) - // - sign MF - // - send to RSU - // - craft ASD object - // - publish back to encoder stream - // CASE 3: If SDW in metadata and ASD in body (double encoding complete) - // - send to SDX - - if (!dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { - logger.debug("Unsigned message received"); - // We don't have ASD, therefore it must be just a MessageFrame that needs to be signed - // No support for unsecured MessageFrame only payload. - // Cases 1 & 2 - // Sign and send to RSUs - - JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); - - String hexEncodedTim = mfObj.getString(BYTES); - logger.debug("Encoded message - phase 1: {}", hexEncodedTim); - //use Asnc1 library to decode the encoded tim returned from ASNC1; another class two blockers: decode the tim and decode the message-sign - - // Case 1: SNMP-deposit - if (dataSigningEnabledRSU && request.getRsus() != null) { - hexEncodedTim = signTIM(hexEncodedTim, consumedObj); - } - else { - // if header is present, strip it - if (isHeaderPresent(hexEncodedTim)) { - String header = hexEncodedTim.substring(0, hexEncodedTim.indexOf("001F") + 4); - logger.debug("Stripping header from unsigned message: {}", header); - hexEncodedTim = stripHeader(hexEncodedTim); - mfObj.remove(BYTES); - mfObj.put(BYTES, hexEncodedTim); - dataObj.remove(MESSAGE_FRAME); - dataObj.put(MESSAGE_FRAME, mfObj); - consumedObj.remove(AppContext.PAYLOAD_STRING); - consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); + } else { + //We have encoded ASD. It could be either UNSECURED or secured. + log.debug("securitySvcsSignatureUri = {}", odeProperties.getSecuritySvcsSignatureUri()); + if (dataSigningEnabledSDW && request.getSdw() != null) { + log.debug("Signed message received. Depositing it to SDW."); + // We have a ASD with signed MessageFrame + // Case 3 + JSONObject asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); + try { + JSONObject deposit = new JSONObject(); + deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); + deposit.put("encodedMsg", asdObj.getString(BYTES)); + asn1CommandManager.depositToSdw(deposit.toString()); + } catch (JSONException | Asn1CommandManagerException e) { + String msg = ERROR_ON_SDX_DEPOSIT; + log.error(msg, e); + } + } else { + log.debug("Unsigned ASD received. Depositing it to SDW."); + //We have ASD with UNSECURED MessageFrame + processEncodedTimUnsecured(request, consumedObj); + } + } + } + + public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consumedObj) { + // Send TIMs and record results + HashMap responseList = new HashMap<>(); + + JSONObject dataObj = consumedObj + .getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING); + + if (null != request.getSdw()) { + JSONObject asdObj = null; + if (dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { + asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); + } else { + log.error("ASD structure present in metadata but not in JSONObject!"); } - } - - if (null != request.getSnmp() && null != request.getRsus() && null != hexEncodedTim) { - logger.info("Sending message to RSUs..."); - asn1CommandManager.sendToRsus(request, hexEncodedTim); - } - - hexEncodedTim = mfObj.getString(BYTES); - - // Case 2: SDX-deposit - if (dataSigningEnabledSDW && request.getSdw() != null) { - hexEncodedTim = signTIM(hexEncodedTim, consumedObj); - } - // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated - depositToFilteredTopic(metadataObj, hexEncodedTim, request); + if (null != asdObj) { + String asdBytes = asdObj.getString(BYTES); + + try { + JSONObject deposit = new JSONObject(); + deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); + deposit.put("encodedMsg", asdBytes); + asn1CommandManager.depositToSdw(deposit.toString()); + log.info("SDX deposit successful."); + } catch (Exception e) { + String msg = ERROR_ON_SDX_DEPOSIT; + log.error(msg, e); + EventLogger.logger.error(msg, e); + } + + } else if (log.isErrorEnabled()) { // Added to avoid Sonar's "Invoke method(s) only conditionally." code smell + String msg = "ASN.1 Encoder did not return ASD encoding {}"; + EventLogger.logger.error(msg, consumedObj); + log.error(msg, consumedObj); + } + } - if (request.getSdw() != null) { - // Case 2 only + if (dataObj.has(MESSAGE_FRAME)) { + JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); + String encodedTim = mfObj.getString(BYTES); - logger.debug("Publishing message for round 2 encoding!"); - String xmlizedMessage = asn1CommandManager.packageSignedTimIntoAsd(request, hexEncodedTim); + // if header is present, strip it + if (isHeaderPresent(encodedTim)) { + String header = encodedTim.substring(0, encodedTim.indexOf("001F") + 4); + log.debug("Stripping header from unsigned message: {}", header); + encodedTim = stripHeader(encodedTim); + mfObj.remove(BYTES); + mfObj.put(BYTES, encodedTim); + dataObj.remove(MESSAGE_FRAME); + dataObj.put(MESSAGE_FRAME, mfObj); + consumedObj.remove(AppContext.PAYLOAD_STRING); + consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); + } - stringMsgProducer.send(odeProperties.getKafkaTopicAsn1EncoderInput(), null, xmlizedMessage); - } + log.debug("Encoded message - phase 2: {}", encodedTim); - } else { - //We have encoded ASD. It could be either UNSECURED or secured. - logger.debug("securitySvcsSignatureUri = {}", odeProperties.getSecuritySvcsSignatureUri()); - if (dataSigningEnabledSDW && request.getSdw() != null) { - logger.debug("Signed message received. Depositing it to SDW."); - // We have a ASD with signed MessageFrame - // Case 3 - JSONObject asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); - try { - JSONObject deposit = new JSONObject(); - deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); - deposit.put("encodedMsg", asdObj.getString(BYTES)); - asn1CommandManager.depositToSdw(deposit.toString()); - } catch (JSONException | Asn1CommandManagerException e) { - String msg = ERROR_ON_SDX_DEPOSIT; - logger.error(msg, e); + // only send message to rsu if snmp, rsus, and message frame fields are present + if (null != request.getSnmp() && null != request.getRsus() && null != encodedTim) { + log.debug("Encoded message phase 3: {}", encodedTim); + asn1CommandManager.sendToRsus(request, encodedTim); } - } else { - logger.debug("Unsigned ASD received. Depositing it to SDW."); - //We have ASD with UNSECURED MessageFrame - processEncodedTimUnsecured(request, consumedObj); - } - } - } - - public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consumedObj) { - // Send TIMs and record results - HashMap responseList = new HashMap<>(); - - JSONObject dataObj = consumedObj - .getJSONObject(AppContext.PAYLOAD_STRING) - .getJSONObject(AppContext.DATA_STRING); - - if (null != request.getSdw()) { - JSONObject asdObj = null; - if (dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { - asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); - } else { - logger.error("ASD structure present in metadata but not in JSONObject!"); - } - - if (null != asdObj) { - String asdBytes = asdObj.getString(BYTES); - + } + + log.info("TIM deposit response {}", responseList); + } + + public String signTIM(String encodedTIM, JSONObject consumedObj) { + log.debug("Sending message for signature! "); + String base64EncodedTim = CodecUtils.toBase64( + CodecUtils.fromHex(encodedTIM)); + JSONObject metadataObjs = consumedObj.getJSONObject(AppContext.METADATA_STRING); + // get max duration time and convert from minutes to milliseconds (unsigned + // integer valid 0 to 2^32-1 in units of + // milliseconds.) from metadata + int maxDurationTime = Integer.valueOf(metadataObjs.get("maxDurationTime").toString()) * 60 * 1000; + String timpacketID = metadataObjs.getString("odePacketID"); + String timStartDateTime = metadataObjs.getString("odeTimStartDateTime"); + String signedResponse = asn1CommandManager.sendForSignature(base64EncodedTim, maxDurationTime); + try { + String hexEncodedTim = CodecUtils.toHex( + CodecUtils.fromBase64( + JsonUtils.toJSONObject(JsonUtils.toJSONObject(signedResponse).getString("result")).getString("message-signed"))); + + JSONObject timWithExpiration = new JSONObject(); + timWithExpiration.put("packetID", timpacketID); + timWithExpiration.put("startDateTime", timStartDateTime); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); try { - JSONObject deposit = new JSONObject(); - deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); - deposit.put("encodedMsg", asdBytes); - asn1CommandManager.depositToSdw(deposit.toString()); - logger.info("SDX deposit successful."); + JSONObject jsonResult = JsonUtils + .toJSONObject((JsonUtils.toJSONObject(signedResponse).getString("result"))); + // messageExpiry uses unit of seconds + long messageExpiry = Long.valueOf(jsonResult.getString("message-expiry")); + timWithExpiration.put("expirationDate", dateFormat.format(new Date(messageExpiry * 1000))); } catch (Exception e) { - String msg = ERROR_ON_SDX_DEPOSIT; - logger.error(msg, e); - EventLogger.logger.error(msg, e); + log.error("Unable to get expiration date from signed messages response ", e); + timWithExpiration.put("expirationDate", "null"); } - } else if (logger.isErrorEnabled()) { // Added to avoid Sonar's "Invoke method(s) only conditionally." code smell - String msg = "ASN.1 Encoder did not return ASD encoding {}"; - EventLogger.logger.error(msg, consumedObj.toString()); - logger.error(msg, consumedObj.toString()); - } - } - - if (dataObj.has(MESSAGE_FRAME)) { - JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); - String encodedTim = mfObj.getString(BYTES); - - // if header is present, strip it - if (isHeaderPresent(encodedTim)) { - String header = encodedTim.substring(0, encodedTim.indexOf("001F") + 4); - logger.debug("Stripping header from unsigned message: {}", header); - encodedTim = stripHeader(encodedTim); - mfObj.remove(BYTES); - mfObj.put(BYTES, encodedTim); - dataObj.remove(MESSAGE_FRAME); - dataObj.put(MESSAGE_FRAME, mfObj); - consumedObj.remove(AppContext.PAYLOAD_STRING); - consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); - } - - logger.debug("Encoded message - phase 2: {}", encodedTim); - - // only send message to rsu if snmp, rsus, and message frame fields are present - if (null != request.getSnmp() && null != request.getRsus() && null != encodedTim) { - logger.debug("Encoded message phase 3: {}", encodedTim); - asn1CommandManager.sendToRsus(request, encodedTim); - } - } - - logger.info("TIM deposit response {}", responseList); - } - - public String signTIM(String encodedTIM, JSONObject consumedObj) { - logger.debug("Sending message for signature! "); - String base64EncodedTim = CodecUtils.toBase64( - CodecUtils.fromHex(encodedTIM)); - JSONObject metadataObjs = consumedObj.getJSONObject(AppContext.METADATA_STRING); - // get max duration time and convert from minutes to milliseconds (unsigned - // integer valid 0 to 2^32-1 in units of - // milliseconds.) from metadata - int maxDurationTime = Integer.valueOf(metadataObjs.get("maxDurationTime").toString()) * 60 * 1000; - String timpacketID = metadataObjs.getString("odePacketID"); - String timStartDateTime = metadataObjs.getString("odeTimStartDateTime"); - String signedResponse = asn1CommandManager.sendForSignature(base64EncodedTim,maxDurationTime); - try { - String hexEncodedTim = CodecUtils.toHex( - CodecUtils.fromBase64( - JsonUtils.toJSONObject(JsonUtils.toJSONObject(signedResponse).getString("result")).getString("message-signed"))); - - JSONObject timWithExpiration = new JSONObject(); - timWithExpiration.put("packetID", timpacketID); - timWithExpiration.put("startDateTime", timStartDateTime); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - try { - JSONObject jsonResult = JsonUtils - .toJSONObject((JsonUtils.toJSONObject(signedResponse).getString("result"))); - // messageExpiry uses unit of seconds - long messageExpiry = Long.valueOf(jsonResult.getString("message-expiry")); - timWithExpiration.put("expirationDate", dateFormat.format(new Date(messageExpiry * 1000))); - } catch (Exception e) { - logger.error("Unable to get expiration date from signed messages response {}", e); - timWithExpiration.put("expirationDate", "null"); - } - - try { - Date parsedtimTimeStamp = dateFormat.parse(timStartDateTime); - Date requiredExpirationDate = new Date(); - requiredExpirationDate.setTime(parsedtimTimeStamp.getTime() + maxDurationTime); - timWithExpiration.put("requiredExpirationDate", dateFormat.format(requiredExpirationDate)); - } catch (Exception e) { - logger.error("Unable to parse requiredExpirationDate {}", e); - timWithExpiration.put("requiredExpirationDate", "null"); - } - //publish to Tim expiration kafka - stringMsgProducer.send(odeProperties.getKafkaTopicSignedOdeTimJsonExpiration(), null, - timWithExpiration.toString()); - - return hexEncodedTim; - - } catch (JsonUtilsException e1) { - logger.error("Unable to parse signed message response {}", e1); - } - return encodedTIM; - } - - /** - * Checks if header is present in encoded message - */ - private boolean isHeaderPresent(String encodedTim) { - return encodedTim.indexOf("001F") > 0; - } - - /** - * Strips header from unsigned message (all bytes before 001F hex value) - */ - private String stripHeader(String encodedUnsignedTim) { - String toReturn = ""; - // find 001F hex value - int index = encodedUnsignedTim.indexOf("001F"); - if (index == -1) { - logger.warn("No '001F' hex value found in encoded message"); - return encodedUnsignedTim; - } - // strip everything before 001F - toReturn = encodedUnsignedTim.substring(index); - return toReturn; - } - - private void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim, ServiceRequest request) { - try { - String generatedBy = metadataObj.getString("recordGeneratedBy"); - String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); - if (generatedBy.equalsIgnoreCase("TMC")) { try { - String timString = odeTimJsonTopology.query(streamId); - - if (timString != null) { - // Set ASN1 data in TIM metadata - JSONObject timJSON = new JSONObject(timString); - JSONObject metadataJSON = timJSON.getJSONObject("metadata"); - metadataJSON.put("asn1", hexEncodedTim); - timJSON.put("metadata", metadataJSON); - - // Send the message w/ asn1 data to the TMC-filtered topic - stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJsonTMCFiltered(), null, timJSON.toString()); - } + Date parsedtimTimeStamp = dateFormat.parse(timStartDateTime); + Date requiredExpirationDate = new Date(); + requiredExpirationDate.setTime(parsedtimTimeStamp.getTime() + maxDurationTime); + timWithExpiration.put("requiredExpirationDate", dateFormat.format(requiredExpirationDate)); } catch (Exception e) { - logger.error("Error while updating TIM: {}", e.getMessage()); + log.error("Unable to parse requiredExpirationDate ", e); + timWithExpiration.put("requiredExpirationDate", "null"); + } + //publish to Tim expiration kafka + stringMsgProducer.send(jsonTopics.getTimCertExpiration(), null, + timWithExpiration.toString()); + + return hexEncodedTim; + + } catch (JsonUtilsException e1) { + log.error("Unable to parse signed message response ", e1); + } + return encodedTIM; + } + + /** + * Checks if header is present in encoded message + */ + private boolean isHeaderPresent(String encodedTim) { + return encodedTim.indexOf("001F") > 0; + } + + /** + * Strips header from unsigned message (all bytes before 001F hex value) + */ + private String stripHeader(String encodedUnsignedTim) { + String toReturn = ""; + // find 001F hex value + int index = encodedUnsignedTim.indexOf("001F"); + if (index == -1) { + log.warn("No '001F' hex value found in encoded message"); + return encodedUnsignedTim; + } + // strip everything before 001F + toReturn = encodedUnsignedTim.substring(index); + return toReturn; + } + + private void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim) { + try { + String generatedBy = metadataObj.getString("recordGeneratedBy"); + String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); + if (!generatedBy.equalsIgnoreCase("TMC")) { + log.debug("Not a TMC-generated TIM. Skipping deposit to TMC-filtered topic."); + return; + } + + String timString = odeTimJsonTopology.query(streamId); + if (timString != null) { + // Set ASN1 data in TIM metadata + JSONObject timJSON = new JSONObject(timString); + JSONObject metadataJSON = timJSON.getJSONObject("metadata"); + metadataJSON.put("asn1", hexEncodedTim); + timJSON.put("metadata", metadataJSON); + + // Send the message w/ asn1 data to the TMC-filtered topic + stringMsgProducer.send(jsonTopics.getTimTmcFiltered(), null, timJSON.toString()); } - } - } catch (Exception e) { - logger.error("Error while fetching recordGeneratedBy field: {}", e.getMessage()); - } - } + } catch (JSONException e) { + log.error("Error while fetching recordGeneratedBy field: {}", e.getMessage()); + } catch (Exception e) { + log.error("Error while updating TIM: {}", e.getMessage()); + } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index 2eb86d271..c0cceded3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -15,51 +15,52 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; -import org.apache.kafka.common.serialization.Serdes; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.*; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /** * Launches ToJsonConverter service */ @Controller +@Slf4j public class AsnCodecRouterServiceController { - private static final Logger logger = LoggerFactory.getLogger(AsnCodecRouterServiceController.class); - Serdes bas; + @Autowired + public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, + OdeKafkaProperties odeKafkaProperties, + JsonTopics jsonTopics, + PojoTopics pojoTopics, + Asn1CoderTopics asn1CoderTopics, + SDXDepositorTopics sdxDepositorTopics) { + super(); - @Autowired - public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - super(); + log.info("Starting {}", this.getClass().getSimpleName()); - logger.info("Starting {}", this.getClass().getSimpleName()); + // asn1_codec Decoder Routing + log.info("Routing DECODED data received ASN.1 Decoder"); - // asn1_codec Decoder Routing - logger.info("Routing DECODED data received ASN.1 Decoder"); + Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeKafkaProperties, pojoTopics, jsonTopics); - Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeProps, odeKafkaProperties); + MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); - MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); + asn1DecoderConsumer.setName("Asn1DecoderConsumer"); + decoderRouter.start(asn1DecoderConsumer, asn1CoderTopics.getDecoderOutput()); - asn1DecoderConsumer.setName("Asn1DecoderConsumer"); - decoderRouter.start(asn1DecoderConsumer, odeProps.getKafkaTopicAsn1DecoderOutput()); + // asn1_codec Encoder Routing + log.info("Routing ENCODED data received ASN.1 Encoder"); - // asn1_codec Encoder Routing - logger.info("Routing ENCODED data received ASN.1 Encoder"); + Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps, odeKafkaProperties, asn1CoderTopics, jsonTopics, sdxDepositorTopics); - Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps, odeKafkaProperties); + MessageConsumer encoderConsumer = MessageConsumer.defaultStringMessageConsumer( + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), encoderRouter); - MessageConsumer encoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), encoderRouter); - - encoderConsumer.setName("Asn1EncoderConsumer"); - encoderRouter.start(encoderConsumer, odeProps.getKafkaTopicAsn1EncoderOutput()); - } + encoderConsumer.setName("Asn1EncoderConsumer"); + encoderRouter.start(encoderConsumer, asn1CoderTopics.getEncoderOutput()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AbstractAsn1DecodeMessageJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AbstractAsn1DecodeMessageJSON.java index 5bcab7e3d..a13d7b892 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AbstractAsn1DecodeMessageJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AbstractAsn1DecodeMessageJSON.java @@ -1,40 +1,34 @@ package us.dot.its.jpo.ode.services.asn1.message; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.fasterxml.jackson.core.JsonProcessingException; - +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.wrapper.AbstractSubscriberProcessor; +@Slf4j public abstract class AbstractAsn1DecodeMessageJSON extends AbstractSubscriberProcessor { - private Logger logger = LoggerFactory.getLogger(this.getClass()); + protected final String publishTopic; protected StringPublisher codecPublisher; - protected String payload_start_flag; - - public AbstractAsn1DecodeMessageJSON() { - super(); - } + protected String payloadStartFlag; - public AbstractAsn1DecodeMessageJSON(StringPublisher codecPublisher, String payload_start_flag) { + protected AbstractAsn1DecodeMessageJSON(String publishTopic, StringPublisher codecPublisher, String payloadStartFlag) { super(); + this.publishTopic = publishTopic; + this.payloadStartFlag = payloadStartFlag; this.codecPublisher = codecPublisher; - this.payload_start_flag = payload_start_flag; } protected void publishEncodedMessageToAsn1Decoder(OdeData odeData) { XmlUtils xmlUtils = new XmlUtils(); try { - logger.debug("Sending encoded message payload XML to ASN1 codec {}", xmlUtils.toXml(odeData)); - codecPublisher.publish(xmlUtils.toXml(odeData), - codecPublisher.getOdeProperties().getKafkaTopicAsn1DecoderInput()); + log.debug("Sending encoded message payload XML to ASN1 codec {}", xmlUtils.toXml(odeData)); + codecPublisher.publish(publishTopic, xmlUtils.toXml(odeData) + ); } catch (JsonProcessingException e) { - logger.error("Error sending encoded message payload XML to ASN1 codec {}", e.getMessage()); - e.printStackTrace(); + log.error("Error sending encoded message payload XML to ASN1 codec {}", e.getMessage(), e); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index eedf1fa32..43494bf49 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,12 +13,16 @@ import us.dot.its.jpo.ode.model.OdeBsmMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeBSMJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); - - public Asn1DecodeBSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getBsmStartFlag()); + private final ObjectMapper objectMapper = new ObjectMapper(); + + public Asn1DecodeBSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getBsmStartFlag() + ); } @Override @@ -38,10 +38,10 @@ protected OdeAsn1Data process(String consumedData) { metadata.addEncoding(unsecuredDataEncoding); String payloadHexString = ((JSONObject)((JSONObject) rawBsmJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-BSM DATA ENCOUNTERED IN THE ASN1DECODEBSMJSON CLASS"); + log.error("NON-BSM DATA ENCOUNTERED IN THE ASN1DECODEBSMJSON CLASS"); return null; } @@ -50,7 +50,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java index c4df633b4..f28bfd923 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,14 +13,16 @@ import us.dot.its.jpo.ode.model.OdeMapMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); - - public Asn1DecodeMAPJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getMapStartFlag()); - } + public Asn1DecodeMAPJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getMapStartFlag() + );} @Override protected OdeAsn1Data process(String consumedData) { @@ -39,10 +37,10 @@ protected OdeAsn1Data process(String consumedData) { metadata.addEncoding(unsecuredDataEncoding); String payloadHexString = ((JSONObject)((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-MAP DATA ENCOUNTERED IN THE ASN1DECODEMAPJSON CLASS"); + log.error("NON-MAP DATA ENCOUNTERED IN THE ASN1DECODEMAPJSON CLASS"); return null; } @@ -51,7 +49,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index 25f96b310..fd7e225dc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,13 +13,16 @@ import us.dot.its.jpo.ode.model.OdePsmMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodePSMJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodePSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getPsmStartFlag()); - } + public Asn1DecodePSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getPsmStartFlag() + );} @Override protected OdeAsn1Data process(String consumedData) { @@ -38,10 +37,10 @@ protected OdeAsn1Data process(String consumedData) { metadata.addEncoding(unsecuredDataEncoding); String payloadHexString = ((JSONObject)((JSONObject) rawPsmJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-PSM DATA ENCOUNTERED IN THE ASN1DECODEPSMJSON CLASS"); + log.error("NON-PSM DATA ENCOUNTERED IN THE ASN1DECODEPSMJSON CLASS"); return null; } @@ -50,7 +49,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index 7223085eb..f6fa8f83f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,12 +13,16 @@ import us.dot.its.jpo.ode.model.OdeSpatMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeSPATJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); - - public Asn1DecodeSPATJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSpatStartFlag()); + private final ObjectMapper objectMapper = new ObjectMapper(); + + public Asn1DecodeSPATJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getSpatStartFlag() + ); } @Override @@ -39,10 +39,10 @@ protected OdeAsn1Data process(String consumedData) { String payloadHexString = ((JSONObject) ((JSONObject) rawSpatJsonObject.get("payload")).get("data")) .getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-SPAT DATA ENCOUNTERED IN THE ASN1DECODESPATJSON CLASS"); + log.error("NON-SPAT DATA ENCOUNTERED IN THE ASN1DECODESPATJSON CLASS"); return null; } @@ -51,7 +51,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 7cd104e9f..9b9e23a70 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,13 +13,16 @@ import us.dot.its.jpo.ode.model.OdeSrmMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeSRMJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSRMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSrmStartFlag()); - } + public Asn1DecodeSRMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getSrmStartFlag() + );} @Override protected OdeAsn1Data process(String consumedData) { @@ -39,10 +38,10 @@ protected OdeAsn1Data process(String consumedData) { String payloadHexString = ((JSONObject) ((JSONObject) rawSrmJsonObject.get("payload")).get("data")) .getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-SRM DATA ENCOUNTERED IN THE ASN1DECODESRMJSON CLASS"); + log.error("NON-SRM DATA ENCOUNTERED IN THE ASN1DECODESRMJSON CLASS"); return null; } @@ -51,7 +50,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index e02800c0c..215d691dd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,13 +13,16 @@ import us.dot.its.jpo.ode.model.OdeSsmMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeSSMJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeSSMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getSsmStartFlag()); - } + public Asn1DecodeSSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getSsmStartFlag() + );} @Override protected OdeAsn1Data process(String consumedData) { @@ -39,10 +38,10 @@ protected OdeAsn1Data process(String consumedData) { String payloadHexString = ((JSONObject) ((JSONObject) rawSsmJsonObject.get("payload")).get("data")) .getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-SSM DATA ENCOUNTERED IN THE ASN1DECODESSMJSON CLASS"); + log.error("NON-SSM DATA ENCOUNTERED IN THE ASN1DECODESSMJSON CLASS"); return null; } @@ -51,7 +50,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index 03f87f8dc..e4948598e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -1,15 +1,11 @@ package us.dot.its.jpo.ode.services.asn1.message; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.ObjectMapper; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -17,13 +13,16 @@ import us.dot.its.jpo.ode.model.OdeTimMetadata; import us.dot.its.jpo.ode.uper.UperUtil; +@Slf4j public class Asn1DecodeTIMJSON extends AbstractAsn1DecodeMessageJSON { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper = new ObjectMapper(); - public Asn1DecodeTIMJSON(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(new StringPublisher(odeProperties, odeKafkaProperties), UperUtil.getTimStartFlag()); - } + public Asn1DecodeTIMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + UperUtil.getTimStartFlag() + );} @Override protected OdeAsn1Data process(String consumedData) { @@ -38,10 +37,10 @@ protected OdeAsn1Data process(String consumedData) { metadata.addEncoding(unsecuredDataEncoding); String payloadHexString = ((JSONObject) ((JSONObject) rawTimJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payload_start_flag); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); if (payloadHexString.equals("BAD DATA")) { - logger.error("NON-TIM DATA ENCOUNTERED IN THE ASN1DECODETIMJSON CLASS"); + log.error("NON-TIM DATA ENCOUNTERED IN THE ASN1DECODETIMJSON CLASS"); return null; } @@ -50,7 +49,7 @@ protected OdeAsn1Data process(String consumedData) { messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); } catch (Exception e) { - logger.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } return messageToPublish; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java index 10281b734..ecee22a05 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java @@ -1,88 +1,78 @@ package us.dot.its.jpo.ode.services.asn1.message; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; - +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /*** * Launch sending encoded message service */ @Controller +@Slf4j public class AsnCodecMessageServiceController { - private static final Logger logger = LoggerFactory.getLogger(AsnCodecMessageServiceController.class); - @Autowired - public AsnCodecMessageServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { + public AsnCodecMessageServiceController(OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics, Asn1CoderTopics asn1CoderTopics) { super(); - logger.info("Starting {} ", this.getClass().getSimpleName()); + log.info("Starting {} ", this.getClass().getSimpleName()); // asn1_codec Decoder Routing - // BSM - logger.info("Send encoded BSM to ASN.1 Decoder"); - Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeProps, odeKafkaProperties); + log.info("Send encoded BSM to ASN.1 Decoder"); + Asn1DecodeBSMJSON asn1DecodeBSMJSON = new Asn1DecodeBSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawBSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeBSMJSON); asn1RawBSMJSONConsumer.setName("asn1DecodeBSMJSON"); - asn1DecodeBSMJSON.start(asn1RawBSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedBSMJson()); + asn1DecodeBSMJSON.start(asn1RawBSMJSONConsumer, rawEncodedJsonTopics.getBsm()); - // SPAT - logger.info("Send encoded SPAT to ASN.1 Decoder"); - Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeProps, odeKafkaProperties); + log.info("Send encoded SPAT to ASN.1 Decoder"); + Asn1DecodeSPATJSON asn1DecodeSPATJSON = new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawSPATJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSPATJSON); asn1RawSPATJSONConsumer.setName("asn1DecodeSPATJSON"); - asn1DecodeSPATJSON.start(asn1RawSPATJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSPATJson()); + asn1DecodeSPATJSON.start(asn1RawSPATJSONConsumer, rawEncodedJsonTopics.getSpat()); - // SSM - logger.info("Send encoded SSM to ASN.1 Decoder"); - Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeProps, odeKafkaProperties); + log.info("Send encoded SSM to ASN.1 Decoder"); + Asn1DecodeSSMJSON asn1DecodeSSMJSON = new Asn1DecodeSSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawSSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSSMJSON); asn1RawSSMJSONConsumer.setName("asn1DecodeSSMJSON"); - asn1DecodeSSMJSON.start(asn1RawSSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSSMJson()); + asn1DecodeSSMJSON.start(asn1RawSSMJSONConsumer, rawEncodedJsonTopics.getSsm()); - // SRM - logger.info("Send encoded SRM to ASN.1 Decoder"); - Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeProps, odeKafkaProperties); + log.info("Send encoded SRM to ASN.1 Decoder"); + Asn1DecodeSRMJSON asn1DecodeSRMJSON = new Asn1DecodeSRMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawSRMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeSRMJSON); asn1RawSRMJSONConsumer.setName("asn1DecodeSRMJSON"); - asn1DecodeSRMJSON.start(asn1RawSRMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedSRMJson()); + asn1DecodeSRMJSON.start(asn1RawSRMJSONConsumer, rawEncodedJsonTopics.getSrm()); - // TIM - logger.info("Send encoded TIM to ASN.1 Decoder"); - Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeProps, odeKafkaProperties); + log.info("Send encoded TIM to ASN.1 Decoder"); + Asn1DecodeTIMJSON asn1DecodeTIMJSON = new Asn1DecodeTIMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawTIMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeTIMJSON); asn1RawTIMJSONConsumer.setName("asn1DecodeTIMJSON"); - asn1DecodeTIMJSON.start(asn1RawTIMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedTIMJson()); + asn1DecodeTIMJSON.start(asn1RawTIMJSONConsumer, rawEncodedJsonTopics.getTim()); - //MAP - logger.info("Send encoded MAP to ASN.1 Decoder"); - Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeProps, odeKafkaProperties); + log.info("Send encoded MAP to ASN.1 Decoder"); + Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSON"); - asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedMAPJson()); + asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, rawEncodedJsonTopics.getMap()); - //PSM - logger.info("Send encoded PSM to ASN.1 Decoder"); - Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeProps, odeKafkaProperties); + log.info("Send encoded PSM to ASN.1 Decoder"); + Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawPSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodePSMSON); asn1RawPSMJSONConsumer.setName("asn1DecodePSMJSON"); - asn1DecodePSMSON.start(asn1RawPSMJSONConsumer, odeProps.getKafkaTopicOdeRawEncodedPSMJson()); + asn1DecodePSMSON.start(asn1RawPSMJSONConsumer, rawEncodedJsonTopics.getPsm()); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java index 1f83b856c..87f314723 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java @@ -16,7 +16,6 @@ package us.dot.its.jpo.ode.services.json; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.AbstractSubPubTransformer; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -26,9 +25,9 @@ */ public class ToJsonConverter extends AbstractSubPubTransformer { - private boolean verbose; + private final boolean verbose; - public ToJsonConverter(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, boolean verbose, String outTopic) { + public ToJsonConverter(OdeKafkaProperties odeKafkaProperties, boolean verbose, String outTopic) { super(MessageProducer.defaultStringMessageProducer( odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java index 0eeef4881..0773d030f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java @@ -15,13 +15,12 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.json; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; - +import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.serdes.OdeBsmDeserializer; @@ -29,30 +28,27 @@ * Launches ToJsonConverter service */ @Controller +@Slf4j public class ToJsonServiceController { - - private static final Logger logger = LoggerFactory.getLogger(ToJsonServiceController.class); - - private OdeProperties odeProps; - private OdeKafkaProperties odeKafkaProperties; + + private final String brokers; @Autowired - public ToJsonServiceController(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { + public ToJsonServiceController(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, PojoTopics pojoTopics) { super(); - this.odeKafkaProperties = odeKafkaProperties; - this.odeProps = odeProperties; + this.brokers = odeKafkaProperties.getBrokers(); // BSM POJO --> JSON converter - launchConverter(odeProps.getKafkaTopicOdeBsmPojo(), OdeBsmDeserializer.class.getName(), - new ToJsonConverter<>(odeProps, odeKafkaProperties, false, odeProps.getKafkaTopicOdeBsmJson())); + launchConverter(pojoTopics.getBsm(), OdeBsmDeserializer.class.getName(), + new ToJsonConverter<>(odeKafkaProperties, false, jsonTopics.getBsm())); } private void launchConverter(String fromTopic, String serializerFQN, ToJsonConverter jsonConverter) { - logger.info("Starting JSON converter, converting records from topic {} and publishing to topic {} ", fromTopic, + log.info("Starting JSON converter, converting records from topic {} and publishing to topic {} ", fromTopic, jsonConverter.getOutputTopic()); - MessageConsumer consumer = new MessageConsumer<>(odeKafkaProperties.getBrokers(), + MessageConsumer consumer = new MessageConsumer<>(this.brokers, this.getClass().getSimpleName(), jsonConverter, serializerFQN); consumer.setName(this.getClass().getName() + fromTopic + "Consumer"); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java index 153d7cb70..78e6d41fc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java @@ -22,6 +22,7 @@ import java.nio.file.Paths; import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -33,24 +34,25 @@ import org.springframework.web.multipart.MultipartFile; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.eventlog.EventLogger; @Service +@Slf4j public class FileSystemStorageService implements StorageService { - private static Logger logger = LoggerFactory.getLogger(FileSystemStorageService.class); private Path rootLocation; private Path logFileLocation; @Autowired - public FileSystemStorageService(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties properties) { + public FileSystemStorageService(FileImporterProperties properties) { this.rootLocation = Paths.get(properties.getUploadLocationRoot()); this.logFileLocation = Paths.get(properties.getUploadLocationRoot(), - properties.getUploadLocationObuLog()); + properties.getObuLogUploadLocation()); - logger.info("Upload location (root): {}", this.rootLocation); - logger.info("Upload location (OBU log file): {}", this.logFileLocation); + log.info("Upload location (root): {}", this.rootLocation); + log.info("Upload location (OBU log file): {}", this.logFileLocation); } @Override @@ -82,7 +84,7 @@ public void store(MultipartFile file, String type) { // Copy the file to the relevant directory try { - logger.debug("Copying file {} to {}", file.getOriginalFilename(), path); + log.debug("Copying file {} to {}", file.getOriginalFilename(), path); EventLogger.logger.info("Copying file {} to {}", file.getOriginalFilename(), path); Files.copy(file.getInputStream(), path); } catch (Exception e) { @@ -137,12 +139,4 @@ public void init() { throw new StorageException("Failed to initialize storage service " + this.rootLocation, e); } } - - public Path getRootLocation() { - return rootLocation; - } - - public void setRootLocation(Path rootLocation) { - this.rootLocation = rootLocation; - } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 2e62fc94d..fa7fbc175 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,38 +15,20 @@ ******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.format.DateTimeParseException; -import java.util.Date; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import com.fasterxml.jackson.databind.node.ObjectNode; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.ConfigEnvironmentVariables; -import us.dot.its.jpo.ode.OdeProperties; +import org.springframework.web.bind.annotation.*; import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.OdeMsgPayload; -import us.dot.its.jpo.ode.model.OdeObject; -import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; -import us.dot.its.jpo.ode.model.OdeTimData; -import us.dot.its.jpo.ode.model.OdeTravelerInputData; -import us.dot.its.jpo.ode.model.SerialId; +import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal.RequestVerb; @@ -63,262 +45,260 @@ import us.dot.its.jpo.ode.wrapper.serdes.OdeTimSerializer; import java.util.UUID; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.format.DateTimeParseException; +import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + @RestController +@Slf4j public class TimDepositController { - private static final Logger logger = LoggerFactory.getLogger(TimDepositController.class); - private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); - - private static final String ERRSTR = "error"; - private static final String WARNING = "warning"; - private static final String SUCCESS = "success"; - - private OdeProperties odeProperties; - private OdeKafkaProperties odeKafkaProperties; - - private SerialId serialIdJ2735; - private SerialId serialIdOde; - - private MessageProducer stringMsgProducer; - private MessageProducer timProducer; - - private boolean dataSigningEnabledSDW; - - public static class TimDepositControllerException extends Exception { - - private static final long serialVersionUID = 1L; - - public TimDepositControllerException(String errMsg) { - super(errMsg); - } - - } - - @Autowired - public TimDepositController(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(); - - this.odeProperties = odeProperties; - this.odeKafkaProperties = odeKafkaProperties; - - this.serialIdJ2735 = new SerialId(); - this.serialIdOde = new SerialId(); - - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); - this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), - null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); - - this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) - : true; - - // start the TIM ingest monitoring service if enabled - boolean timIngestMonitoringEnabled = Boolean.parseBoolean(odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_ENABLED)); - if (timIngestMonitoringEnabled) { - logger.info("TIM ingest monitoring enabled."); - - ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - // 3600 seconds, or one hour, was determined to be a sane default for the monitoring interval if monitoring is enabled - // but there was no interval set in the .env file - String interval = odeProperties.getProperty(ConfigEnvironmentVariables.ODE_TIM_INGEST_MONITORING_INTERVAL); - long monitoringInterval; - try { - monitoringInterval = Long.parseLong(interval); - } catch (NumberFormatException e) { - monitoringInterval = 3600; - } - - scheduledExecutorService.scheduleAtFixedRate(new TimIngestWatcher(monitoringInterval), monitoringInterval, monitoringInterval, java.util.concurrent.TimeUnit.SECONDS); - } else { - logger.info("TIM ingest monitoring disabled."); - } - } - - /** - * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST - * - * @param jsonString - * @param verb - * @return - */ - public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { - - if (null == jsonString || jsonString.isEmpty()) { - String errMsg = "Empty request."; - logger.error(errMsg); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - OdeTravelerInputData odeTID = null; - ServiceRequest request; - try { - // Convert JSON to POJO - odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, OdeTravelerInputData.class, true); - if (odeTID == null) { + private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); + + private static final String ERRSTR = "error"; + private static final String WARNING = "warning"; + private static final String SUCCESS = "success"; + + private final Asn1CoderTopics asn1CoderTopics; + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; + + private final SerialId serialIdJ2735; + private final SerialId serialIdOde; + + private final MessageProducer stringMsgProducer; + private final MessageProducer timProducer; + + private final boolean dataSigningEnabledSDW; + + public static class TimDepositControllerException extends Exception { + + private static final long serialVersionUID = 1L; + + public TimDepositControllerException(String errMsg) { + super(errMsg); + } + + } + + @Autowired + public TimDepositController(OdeKafkaProperties odeKafkaProperties, Asn1CoderTopics asn1CoderTopics, PojoTopics pojoTopics, JsonTopics jsonTopics, TimIngestTrackerProperties ingestTrackerProperties) { + super(); + + this.asn1CoderTopics = asn1CoderTopics; + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + this.serialIdJ2735 = new SerialId(); + this.serialIdOde = new SerialId(); + + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); + + this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") == null || System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() || Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")); + + // start the TIM ingest monitoring service if enabled + if (ingestTrackerProperties.isTrackingEnabled()) { + log.info("TIM ingest monitoring enabled."); + + ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); + + scheduledExecutorService.scheduleAtFixedRate( + new TimIngestWatcher(ingestTrackerProperties.getInterval()), + ingestTrackerProperties.getInterval(), + ingestTrackerProperties.getInterval(), + java.util.concurrent.TimeUnit.SECONDS); + } else { + log.info("TIM ingest monitoring disabled."); + } + } + + /** + * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST + * + * @param jsonString + * @param verb + * @return + */ + public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { + + if (null == jsonString || jsonString.isEmpty()) { + String errMsg = "Empty request."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + OdeTravelerInputData odeTID = null; + ServiceRequest request; + try { + // Convert JSON to POJO + odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, OdeTravelerInputData.class, true); + if (odeTID == null) { + String errMsg = "Malformed or non-compliant JSON syntax."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + request = odeTID.getRequest(); + if (request == null) { + throw new TimDepositControllerException("Request element is required as of version 3."); + } + + if (request.getOde() == null) { + request.setOde(new OdeInternal()); + } + + request.getOde().setVerb(verb); + + } catch (TimDepositControllerException e) { + String errMsg = "Missing or invalid argument: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } catch (JsonUtilsException e) { String errMsg = "Malformed or non-compliant JSON syntax."; - logger.error(errMsg); + log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - request = odeTID.getRequest(); - if (request == null) { - throw new TimDepositControllerException("Request element is required as of version 3."); - } - - if (request.getOde() == null) { - request.setOde(new OdeInternal()); - } - - request.getOde().setVerb(verb); - - } catch (TimDepositControllerException e) { - String errMsg = "Missing or invalid argument: " + e.getMessage(); - logger.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } catch (JsonUtilsException e) { - String errMsg = "Malformed or non-compliant JSON syntax."; - logger.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - // Add metadata to message and publish to kafka - OdeTravelerInformationMessage tim = odeTID.getTim(); - OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); - OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); - - // set packetID in tim Metadata - timMetadata.setOdePacketID(tim.getPacketID()); - // set maxDurationTime in tim Metadata and set latest startDatetime in tim - // metadata - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - if (null != tim.getDataframes() && tim.getDataframes().length > 0) { - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = maxDurationTime > dataFrameItem.getDurationTime() ? maxDurationTime - : dataFrameItem.getDurationTime(); - try { - latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null - && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime); - } catch (ParseException e) { - logger.error("Invalid dateTime parse: " + e); + } + + // Add metadata to message and publish to kafka + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + + // set packetID in tim Metadata + timMetadata.setOdePacketID(tim.getPacketID()); + // set maxDurationTime in tim Metadata and set latest startDatetime in tim + // metadata + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + if (null != tim.getDataframes() && tim.getDataframes().length > 0) { + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = maxDurationTime > dataFrameItem.getDurationTime() ? maxDurationTime + : dataFrameItem.getDurationTime(); + try { + latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null + && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime); + } catch (ParseException e) { + log.error("Invalid dateTime parse: " + e); + } } - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); - } - // Setting the SerialId to OdeBradcastTim serialId to be changed to - // J2735BroadcastTim serialId after the message has been published to - // OdeTimBrodcast topic - timMetadata.setSerialId(serialIdOde); - timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); - - try { - timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); - } catch (ParseException | DateTimeParseException e) { - String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); - logger.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); - timProducer.send(odeProperties.getKafkaTopicOdeTimBroadcastPojo(), null, odeTimData); - - String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); - stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimBroadcastJson(), null, obfuscatedTimData); - - // Now that the message gas been published to OdeBradcastTim topic, it should be - // changed to J2735BroadcastTim serialId - timMetadata.setSerialId(serialIdJ2735); - - // Short circuit - // If the TIM has no RSU/SNMP or SDW structures, we are done - if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { - String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams."; - logger.warn(warningMsg); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); - } - - // Craft ASN-encodable TIM - ObjectNode encodableTid; - try { - encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - - logger.debug("Encodable Traveler Information Data: {}", encodableTid); - - } catch (JsonUtilsException e) { - String errMsg = "Error converting to encodable TravelerInputData."; - logger.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - try { - logger.debug("securitySvcsSignatureUri = {}", odeProperties.getSecuritySvcsSignatureUri()); - String xmlMsg; - DdsAdvisorySituationData asd = null; - if (!this.dataSigningEnabledSDW) { - // We need to send data UNSECURED, so we should try to build the ASD as well as - // MessageFrame - asd = TimTransmogrifier.buildASD(odeTID.getRequest()); - } - xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); - logger.debug("XML representation: {}", xmlMsg); - - JSONObject jsonMsg = XmlUtils.toJSONObject(xmlMsg); - - String j2735Tim = TimTransmogrifier.createOdeTimData(jsonMsg.getJSONObject(AppContext.ODE_ASN1_DATA)) - .toString(); - - stringMsgProducer.send(odeProperties.getKafkaTopicAsn1EncoderInput(), null, xmlMsg); - - String obfuscatedj2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - // publish Broadcast TIM to a J2735 compliant topic. - stringMsgProducer.send(odeProperties.getKafkaTopicJ2735TimBroadcastJson(), null, obfuscatedj2735Tim); - // publish J2735 TIM also to general un-filtered TIM topic - // with streamID as key - stringMsgProducer.send(odeProperties.getKafkaTopicOdeTimJson(), serialIdJ2735.getStreamId(), obfuscatedj2735Tim); - - serialIdOde.increment(); - serialIdJ2735.increment(); - } catch (JsonUtils.JsonUtilsException | XmlUtils.XmlUtilsException | TimTransmogrifierException e) { - String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); - logger.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - INGEST_MONITOR.incrementTotalMessagesReceived(); - - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); - } - - /** - * Update an already-deposited TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PutMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity putTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); - } - - /** - * Deposit a new TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PostMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity postTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); - } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + } + // Setting the SerialId to OdeBradcastTim serialId to be changed to + // J2735BroadcastTim serialId after the message has been published to + // OdeTimBrodcast topic + timMetadata.setSerialId(serialIdOde); + timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); + + try { + timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + } catch (ParseException | DateTimeParseException e) { + String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); + timProducer.send(pojoTopics.getTimBroadcast(), null, odeTimData); + + String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); + stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); + + // Now that the message gas been published to OdeBradcastTim topic, it should be + // changed to J2735BroadcastTim serialId + timMetadata.setSerialId(serialIdJ2735); + + // Short circuit + // If the TIM has no RSU/SNMP or SDW structures, we are done + if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { + String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams."; + log.warn(warningMsg); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); + } + + // Craft ASN-encodable TIM + ObjectNode encodableTid; + try { + encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); + + log.debug("Encodable Traveler Information Data: {}", encodableTid); + + } catch (JsonUtilsException e) { + String errMsg = "Error converting to encodable TravelerInputData."; + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + try { + String xmlMsg; + DdsAdvisorySituationData asd = null; + if (!this.dataSigningEnabledSDW) { + // We need to send data UNSECURED, so we should try to build the ASD as well as + // MessageFrame + asd = TimTransmogrifier.buildASD(odeTID.getRequest()); + } + xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); + log.debug("XML representation: {}", xmlMsg); + + JSONObject jsonMsg = XmlUtils.toJSONObject(xmlMsg); + + String j2735Tim = TimTransmogrifier.createOdeTimData(jsonMsg.getJSONObject(AppContext.ODE_ASN1_DATA)) + .toString(); + + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); + + String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); + // publish Broadcast TIM to a J2735 compliant topic. + stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); + // publish J2735 TIM also to general un-filtered TIM topic + // with streamID as key + stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); + + serialIdOde.increment(); + serialIdJ2735.increment(); + } catch (JsonUtils.JsonUtilsException | XmlUtils.XmlUtilsException | TimTransmogrifierException e) { + String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + INGEST_MONITOR.incrementTotalMessagesReceived(); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); + } + + /** + * Update an already-deposited TIM + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PutMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity putTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); + } + + /** + * Deposit a new TIM + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PostMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity postTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidator.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidator.java new file mode 100644 index 000000000..4a5c2bd17 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidator.java @@ -0,0 +1,20 @@ +package us.dot.its.jpo.ode.traveler; + +import org.springframework.validation.Validator; + +public class TimIngestPropertiesValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return TimIngestTrackerProperties.class.equals(clazz); + } + + @Override + public void validate(Object target, org.springframework.validation.Errors errors) { + TimIngestTrackerProperties properties = (TimIngestTrackerProperties) target; + + if (properties.isTrackingEnabled() && properties.getInterval() <= 0) { + errors.rejectValue("interval", "interval.invalid", "Monitoring interval must be greater than 0"); + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerProperties.java new file mode 100644 index 000000000..e70ca4f0d --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerProperties.java @@ -0,0 +1,15 @@ +package us.dot.its.jpo.ode.traveler; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +@Configuration +@ConfigurationProperties(prefix = "ode.tim-ingest-monitoring") +@Validated(value = TimIngestPropertiesValidator.class) +@Data +public class TimIngestTrackerProperties { + private boolean trackingEnabled; + private long interval = 3600; // in seconds. Default is 1 hour (3600 seconds) +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java index 73ef59562..2104d6a73 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java @@ -108,20 +108,20 @@ public synchronized ResponseEntity bulkQuery(@RequestBody String jsonStr } if (snmpProtocol == SnmpProtocol.FOURDOT1) { - for (int i = 0; i < odeProperties.getRsuSrmSlots() - 50; i++) { + for (int i = 0; i < odeProperties.rsuProperties().getSrmSlots() - 50; i++) { pdu0.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); } - for (int i = 50; i < odeProperties.getRsuSrmSlots(); i++) { + for (int i = 50; i < odeProperties.rsuProperties().getSrmSlots(); i++) { pdu1.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); } } else if (snmpProtocol == SnmpProtocol.NTCIP1218) { - for (int i = 0; i < odeProperties.getRsuSrmSlots() - 50; i++) { + for (int i = 0; i < odeProperties.rsuProperties().getSrmSlots() - 50; i++) { pdu0.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); } - for (int i = 50; i < odeProperties.getRsuSrmSlots(); i++) { + for (int i = 50; i < odeProperties.rsuProperties().getSrmSlots(); i++) { pdu1.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java index 21eca8508..ea237d21e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java @@ -223,11 +223,11 @@ private static ArrayNode buildEncodings(DdsAdvisorySituationData asd) throws Jso public static void updateRsuCreds(RSU rsu, OdeProperties odeProperties) { if (rsu.getRsuUsername() == null || rsu.getRsuUsername().isEmpty()) { - rsu.setRsuUsername(odeProperties.getRsuUsername()); + rsu.setRsuUsername(odeProperties.rsuProperties().getUsername()); } if (rsu.getRsuPassword() == null || rsu.getRsuPassword().isEmpty()) { - rsu.setRsuPassword(odeProperties.getRsuPassword()); + rsu.setRsuPassword(odeProperties.rsuProperties().getPassword()); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java index 449282c72..595b9663b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java @@ -1,55 +1,51 @@ package us.dot.its.jpo.ode.udp; +import lombok.extern.slf4j.Slf4j; +import us.dot.its.jpo.ode.OdeProperties; + import java.net.DatagramSocket; import java.net.SocketException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import us.dot.its.jpo.ode.OdeProperties; - +@Slf4j public abstract class AbstractUdpReceiverPublisher implements Runnable { - public class UdpReceiverException extends Exception { - private static final long serialVersionUID = 1L; + public class UdpReceiverException extends Exception { + private static final long serialVersionUID = 1L; - public UdpReceiverException(String string, Exception e) { - super(string, e); - } - } + public UdpReceiverException(String string, Exception e) { + super(string, e); + } + } - private static Logger logger = LoggerFactory.getLogger(AbstractUdpReceiverPublisher.class); - protected DatagramSocket socket; + protected DatagramSocket socket; - protected String senderIp; - protected int senderPort; + protected String senderIp; + protected int senderPort; - protected OdeProperties odeProperties; - protected int port; - protected int bufferSize; + protected OdeProperties odeProperties; + protected int port; + protected int bufferSize; - private boolean stopped = false; + private boolean stopped = false; - public boolean isStopped() { - return stopped; - } + public boolean isStopped() { + return stopped; + } - public void setStopped(boolean stopped) { - this.stopped = stopped; - } + public void setStopped(boolean stopped) { + this.stopped = stopped; + } - protected AbstractUdpReceiverPublisher(OdeProperties odeProps, int port, int bufferSize) { - this.odeProperties = odeProps; - this.port = port; - this.bufferSize = bufferSize; + protected AbstractUdpReceiverPublisher(int port, int bufferSize) { + this.port = port; + this.bufferSize = bufferSize; - try { - this.socket = new DatagramSocket(this.port); - logger.info("Created UDP socket bound to port {}", this.port); - } catch (SocketException e) { - logger.error("Error creating socket with port " + this.port, e); - } - } + try { + this.socket = new DatagramSocket(this.port); + log.info("Created UDP socket bound to port {}", this.port); + } catch (SocketException e) { + log.error("Error creating socket with port {}", this.port, e); + } + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index fe1707a33..43d9b7367 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -1,61 +1,52 @@ package us.dot.its.jpo.ode.udp.bsm; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -public class BsmReceiver extends AbstractUdpReceiverPublisher { - - private static Logger logger = LoggerFactory.getLogger(BsmReceiver.class); +import java.net.DatagramPacket; - private final StringPublisher bsmPublisher; +@Slf4j +public class BsmReceiver extends AbstractUdpReceiverPublisher { - @Autowired - public BsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getBsmReceiverPort(), odeProps.getBsmBufferSize()); - } + private final StringPublisher bsmPublisher; + private final String publishTopic; - public BsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public BsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.bsmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); - } + this.publishTopic = publishTopic; + this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + } - @Override - public void run() { + @Override + public void run() { - logger.debug("BSM UDP Receiver Service started."); + log.debug("BSM UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; + byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - logger.debug("Waiting for UDP BSM packets..."); - this.socket.receive(packet); - if (packet.getLength() > 0) { - String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); + do { + try { + log.debug("Waiting for UDP BSM packets..."); + this.socket.receive(packet); + if (packet.getLength() > 0) { + String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - if(bsmJson != null){ - bsmPublisher.publish(bsmJson, bsmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedBSMJson()); - } - - + if (bsmJson != null) { + bsmPublisher.publish(publishTopic, bsmJson); + } + } + } catch (Exception e) { + log.error("Error receiving packet", e); } - } catch (Exception e) { - logger.error("Error receiving packet", e); - } - } while (!isStopped()); - } + } while (!isStopped()); + } + - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java new file mode 100644 index 000000000..9fdbb2ee7 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.udp.controller; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.receivers") +@Data +public class UDPReceiverProperties { + private ReceiverProperties generic; + private ReceiverProperties bsm; + private ReceiverProperties map; + private ReceiverProperties psm; + private ReceiverProperties spat; + private ReceiverProperties srm; + private ReceiverProperties ssm; + private ReceiverProperties tim; + + @Data + public static class ReceiverProperties { + private int receiverPort; + private int bufferSize; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index 3df7a4c2c..882aaa354 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -1,13 +1,10 @@ package us.dot.its.jpo.ode.udp.controller; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; - import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; 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; @@ -19,46 +16,27 @@ /** * Centralized UDP service dispatcher. - * */ @Controller +@Slf4j public class UdpServicesController { - private Logger logger = LoggerFactory.getLogger(UdpServicesController.class); - - @Autowired - public UdpServicesController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - super(); - - // Start the UDP receivers - ServiceManager rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); - - logger.debug("Starting UDP receiver services..."); - - // BSM internal - rm.submit(new BsmReceiver(odeProps, odeKafkaProperties)); - - // TIM internal - rm.submit(new TimReceiver(odeProps, odeKafkaProperties)); - - // SSM internal port - rm.submit(new SsmReceiver(odeProps, odeKafkaProperties)); - - // SRM internal port - rm.submit(new SrmReceiver(odeProps, odeKafkaProperties)); - - // SPAT internal port - rm.submit(new SpatReceiver(odeProps, odeKafkaProperties)); - - // MAP internal port - rm.submit(new MapReceiver(odeProps, odeKafkaProperties)); + @Autowired + public UdpServicesController(UDPReceiverProperties udpProps, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { + super(); - // PSM internal port - rm.submit(new PsmReceiver(odeProps, odeKafkaProperties)); + ServiceManager rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); + log.debug("Starting UDP receiver services..."); - // Generic Receiver internal port - rm.submit(new GenericReceiver(odeProps, odeKafkaProperties)); + rm.submit(new BsmReceiver(udpProps.getBsm(), odeKafkaProperties, rawEncodedJsonTopics.getBsm())); + rm.submit(new TimReceiver(udpProps.getTim(), odeKafkaProperties, rawEncodedJsonTopics.getTim())); + rm.submit(new SsmReceiver(udpProps.getSsm(), odeKafkaProperties, rawEncodedJsonTopics.getSsm())); + rm.submit(new SrmReceiver(udpProps.getSrm(), odeKafkaProperties, rawEncodedJsonTopics.getSrm())); + rm.submit(new SpatReceiver(udpProps.getSpat(), odeKafkaProperties, rawEncodedJsonTopics.getSpat())); + rm.submit(new MapReceiver(udpProps.getMap(), odeKafkaProperties, rawEncodedJsonTopics.getMap())); + rm.submit(new PsmReceiver(udpProps.getPsm(), odeKafkaProperties, rawEncodedJsonTopics.getPsm())); + rm.submit(new GenericReceiver(udpProps.getGeneric(), odeKafkaProperties, rawEncodedJsonTopics)); - logger.debug("UDP receiver services started."); - } + log.debug("UDP receiver services started."); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index 2d6e7bb50..0dc994ef1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -1,112 +1,108 @@ package us.dot.its.jpo.ode.udp.generic; -import java.net.DatagramPacket; +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.uper.UperUtil; -public class GenericReceiver extends AbstractUdpReceiverPublisher { +import java.net.DatagramPacket; - private static Logger logger = LoggerFactory.getLogger(GenericReceiver.class); +@Slf4j +public class GenericReceiver extends AbstractUdpReceiverPublisher { private final StringPublisher publisher; + private final RawEncodedJsonTopics rawEncodedJsonTopics; - @Autowired - public GenericReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getGenericReceiverPort(), odeProps.getGenericBufferSize()); - } - - public GenericReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public GenericReceiver(UDPReceiverProperties.ReceiverProperties props, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { + super(props.getReceiverPort(), props.getBufferSize()); - this.publisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.rawEncodedJsonTopics = rawEncodedJsonTopics; } @Override public void run() { + log.debug("Generic UDP Receiver Service started."); - logger.debug("Generic UDP Receiver Service started."); - - byte[] buffer = new byte[bufferSize]; - - - + byte[] buffer; do { - buffer = new byte[bufferSize]; + buffer = new byte[bufferSize]; // packet should be recreated on each loop to prevent latent data in buffer DatagramPacket packet = new DatagramPacket(buffer, buffer.length); try { - logger.debug("Waiting for Generic UDP packets..."); + log.debug("Waiting for Generic UDP packets..."); socket.receive(packet); - if (packet.getLength() > 0) { - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + byte[] payload = packet.getData(); + if ((packet.getLength() <= 0) || (payload == null)) { + log.debug("Skipping empty payload"); + continue; + } - byte[] payload = packet.getData(); - if (payload == null){ - logger.debug("Skipping Null Payload"); - continue; - } - String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); - logger.debug("Raw Payload" + payloadHexString); - - String messageType = UperUtil.determineHexPacketType(payloadHexString); + senderIp = packet.getAddress().getHostAddress(); + senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + log.debug("Raw Payload {}", payloadHexString); - logger.debug("Detected Message Type {}", messageType); + String messageType = UperUtil.determineHexPacketType(payloadHexString); - if (messageType.equals("MAP")) { + log.debug("Detected Message Type {}", messageType); + + switch (messageType) { + case "MAP" -> { String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); - logger.debug("Sending Data to Topic" + mapJson); - if(mapJson != null){ - publisher.publish(mapJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); + log.debug("Sending Data to Topic {}", mapJson); + if (mapJson != null) { + publisher.publish(rawEncodedJsonTopics.getMap(), mapJson); } - } else if(messageType.equals("SPAT")) { + } + case "SPAT" -> { String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); - if(spatJson != null){ - publisher.publish(spatJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + if (spatJson != null) { + publisher.publish(rawEncodedJsonTopics.getSpat(), spatJson); } - } else if (messageType.equals("TIM")) { + } + case "TIM" -> { String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); - if(timJson != null){ - publisher.publish(timJson, publisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); + if (timJson != null) { + publisher.publish(rawEncodedJsonTopics.getTim(), timJson); } - } else if (messageType.equals("BSM")) { + } + case "BSM" -> { String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - if(bsmJson!=null){ - publisher.publish(bsmJson, this.odeProperties.getKafkaTopicOdeRawEncodedBSMJson()); + if (bsmJson != null) { + publisher.publish(rawEncodedJsonTopics.getBsm(), bsmJson); } - } else if (messageType.equals("SSM")) { + } + case "SSM" -> { String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - if(ssmJson!=null){ - publisher.publish(ssmJson, this.odeProperties.getKafkaTopicOdeRawEncodedSSMJson()); + if (ssmJson != null) { + publisher.publish(rawEncodedJsonTopics.getSsm(), ssmJson); } - } else if (messageType.equals("SRM")) { + } + case "SRM" -> { String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); - if(srmJson!=null){ - publisher.publish(srmJson, this.odeProperties.getKafkaTopicOdeRawEncodedSRMJson()); + if (srmJson != null) { + publisher.publish(rawEncodedJsonTopics.getSrm(), srmJson); } - } else if (messageType.equals("PSM")) { + } + case "PSM" -> { String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); - if(psmJson!=null){ - publisher.publish(psmJson, this.odeProperties.getKafkaTopicOdeRawEncodedPSMJson()); + if (psmJson != null) { + publisher.publish(rawEncodedJsonTopics.getPsm(), psmJson); } - }else{ - logger.debug("Unknown Message Type"); } + default -> log.debug("Unknown Message Type"); } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); - } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index bf9b4fe5d..eed9651ab 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -1,60 +1,50 @@ package us.dot.its.jpo.ode.udp.map; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -public class MapReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(MapReceiver.class); +import java.net.DatagramPacket; +@Slf4j +public class MapReceiver extends AbstractUdpReceiverPublisher { private final StringPublisher mapPublisher; + private final String publishTopic; - @Autowired - public MapReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getMapReceiverPort(), odeProps.getMapBufferSize()); - } - - public MapReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.mapPublisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publishTopic = publishTopic; + this.mapPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - - logger.debug("Map UDP Receiver Service started."); + log.debug("Map UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); do { try { - logger.debug("Waiting for UDP Map packets..."); + log.debug("Waiting for UDP Map packets..."); socket.receive(packet); if (packet.getLength() > 0) { - + String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); - if(mapJson != null){ - mapPublisher.publish(mapJson, mapPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedMAPJson()); + if (mapJson != null) { + mapPublisher.publish(this.publishTopic, mapJson); } - + } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); } - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index d535b067b..fe884fc5c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -1,57 +1,49 @@ package us.dot.its.jpo.ode.udp.psm; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -public class PsmReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(PsmReceiver.class); +import java.net.DatagramPacket; - private StringPublisher psmPublisher; +@Slf4j +public class PsmReceiver extends AbstractUdpReceiverPublisher { - @Autowired - public PsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getPsmReceiverPort(), odeProps.getPsmBufferSize()); - } + private final StringPublisher psmPublisher; + private final String publishTopic; - public PsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public PsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.psmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publishTopic = publishTopic; + this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - - logger.debug("PSM UDP Receiver Service started."); + log.debug("PSM UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); do { try { - logger.debug("Waiting for UDP PSM packets..."); + log.debug("Waiting for UDP PSM packets..."); socket.receive(packet); if (packet.getLength() > 0) { String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); - if(psmJson != null){ - psmPublisher.publish(psmJson, psmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedPSMJson()); + if (psmJson != null) { + psmPublisher.publish(this.publishTopic, psmJson); } } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); } - + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index cb8ed0e5a..5dbc38a5f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -1,37 +1,31 @@ package us.dot.its.jpo.ode.udp.spat; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import java.net.DatagramPacket; + +@Slf4j public class SpatReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(SpatReceiver.class); private final StringPublisher spatPublisher; + private final String publishTopic; - @Autowired - public SpatReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getSpatReceiverPort(), odeProps.getSpatBufferSize()); - } - - public SpatReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public SpatReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.spatPublisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publishTopic = publishTopic; + this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - logger.debug("SPaT UDP Receiver Service started."); + log.debug("SPaT UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; @@ -39,20 +33,19 @@ public void run() { do { try { - logger.debug("Waiting for UDP SPaT packets..."); + log.debug("Waiting for UDP SPaT packets..."); socket.receive(packet); if (packet.getLength() > 0) { String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); - if(spatJson != null){ - spatPublisher.publish(spatJson,spatPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSPATJson()); + if (spatJson != null) { + spatPublisher.publish(this.publishTopic, spatJson); } } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); } - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index a541a080d..71b2f02e7 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -3,29 +3,24 @@ import java.net.DatagramPacket; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; public class SrmReceiver extends AbstractUdpReceiverPublisher { private static Logger logger = LoggerFactory.getLogger(SrmReceiver.class); private final StringPublisher srmPublisher; + private final String publishTopic; - @Autowired - public SrmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getSrmReceiverPort(), odeProps.getSrmBufferSize()); - } - - public SrmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + public SrmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.srmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publishTopic = publishTopic; + this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); } @Override @@ -45,7 +40,7 @@ public void run() { String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); if(srmJson != null){ - srmPublisher.publish(srmJson, srmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSRMJson()); + srmPublisher.publish(publishTopic, srmJson); } } } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index f193fbcfd..89af94ae5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -1,60 +1,52 @@ package us.dot.its.jpo.ode.udp.ssm; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import org.springframework.beans.factory.annotation.Qualifier; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import java.net.DatagramPacket; + +@Slf4j public class SsmReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(SsmReceiver.class); private final StringPublisher ssmPublisher; + private final String publishTopic; - @Autowired - public SsmReceiver(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getSsmReceiverPort(), odeProps.getSsmBufferSize()); - } + public SsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - public SsmReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); - - this.ssmPublisher = new StringPublisher(odeProperties, odeKafkaProperties); + this.publishTopic = publishTopic; + this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - - logger.debug("SSM UDP Receiver Service started."); + log.debug("SSM UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); do { try { - logger.debug("Waiting for UDP SSM packets..."); + log.debug("Waiting for UDP SSM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - + String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - if(ssmJson!=null){ - ssmPublisher.publish(ssmJson, ssmPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedSSMJson()); + if (ssmJson != null) { + ssmPublisher.publish(this.publishTopic, ssmJson); } - + } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); } - + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 87c4894b7..5d2e43636 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -1,59 +1,52 @@ package us.dot.its.jpo.ode.udp.tim; -import java.net.DatagramPacket; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.OdeProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; + +import java.net.DatagramPacket; +@Slf4j public class TimReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(TimReceiver.class); - private StringPublisher timPublisher; + private final StringPublisher timPublisher; + private final String publishTopic; - @Autowired - public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties) { - this(odeProps, odeKafkaProperties, odeProps.getTimReceiverPort(), odeProps.getTimBufferSize()); - } + public TimReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - public TimReceiver(OdeProperties odeProps, OdeKafkaProperties odeKafkaProperties, int port, int bufferSize) { - super(odeProps, port, bufferSize); + this.publishTopic = publishTopic; + this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + } - this.timPublisher = new StringPublisher(odeProperties, odeKafkaProperties); - } + @Override + public void run() { + log.debug("TIM UDP Receiver Service started."); - @Override - public void run() { - logger.debug("TIM UDP Receiver Service started."); + byte[] buffer = new byte[bufferSize]; - byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP TIM packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { - do { - try { - logger.debug("Waiting for UDP TIM packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - - String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); - if(timJson != null){ - timPublisher.publish(timJson, timPublisher.getOdeProperties().getKafkaTopicOdeRawEncodedTIMJson()); - } - + String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); + if (timJson != null) { + timPublisher.publish(publishTopic, timJson); + } + + } + } catch (Exception e) { + log.error("Error receiving packet", e); } - } catch (Exception e) { - logger.error("Error receiving packet", e); - } - } while (!isStopped()); - } + } while (!isStopped()); + } + - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java index 44c88d9a4..a69b84779 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,94 +15,87 @@ ******************************************************************************/ package us.dot.its.jpo.ode.upload; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.messaging.simp.SimpMessagingTemplate; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.exporter.StompStringExporter; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; -import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; +import us.dot.its.jpo.ode.kafka.FileTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; import us.dot.its.jpo.ode.storage.StorageService; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Slf4j @RestController public class FileUploadController { - private static final String FILTERED_OUTPUT_TOPIC = "/topic/filtered_messages"; - private static final String UNFILTERED_OUTPUT_TOPIC = "/topic/unfiltered_messages"; - - private static Logger logger = LoggerFactory.getLogger(FileUploadController.class); - - private final StorageService storageService; - - @Autowired - public FileUploadController( - StorageService storageService, OdeProperties odeProperties, - OdeKafkaProperties odeKafkaProperties, SimpMessagingTemplate template) { - super(); - this.storageService = storageService; - - ExecutorService threadPool = Executors.newCachedThreadPool(); - - Path logPath = Paths.get(odeProperties.getUploadLocationRoot(), - odeProperties.getUploadLocationObuLog()); - logger.debug("UPLOADER - BSM log file upload directory: {}", logPath); - Path failurePath = Paths.get(odeProperties.getUploadLocationRoot(), "failed"); - logger.debug("UPLOADER - Failure directory: {}", failurePath); - Path backupPath = Paths.get(odeProperties.getUploadLocationRoot(), "backup"); - logger.debug("UPLOADER - Backup directory: {}", backupPath); - - // Create the importers that watch folders for new/modified files - threadPool.submit(new ImporterDirectoryWatcher(odeProperties, odeKafkaProperties, logPath, backupPath, failurePath, ImporterFileType.LOG_FILE, odeProperties.getFileWatcherPeriod())); - - // Create unfiltered exporters - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSpatJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeMapJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSsmJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeSrmJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicDriverAlertJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, UNFILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicOdeTimBroadcastJson())); - - // Create filtered exporters - threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeBsmJson())); - threadPool.submit(new StompStringExporter(odeKafkaProperties, FILTERED_OUTPUT_TOPIC, template, odeProperties.getKafkaTopicFilteredOdeTimJson())); - } - - @PostMapping("/upload/{type}") - public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable("type") String type) { - - logger.debug("File received at endpoint: /upload/{}, name={}", type, file.getOriginalFilename()); - try { - storageService.store(file, type); - } catch (Exception e) { - logger.error("File storage error", e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"Error\": \"File storage error.\"}"); - // do not return exception, XSS vulnerable - } - - return ResponseEntity.status(HttpStatus.OK).body("{\"Success\": \"True\"}"); - } - - @ExceptionHandler(StorageFileNotFoundException.class) - public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) { - return ResponseEntity.notFound().build(); - } + private final StorageService storageService; + + @Autowired + public FileUploadController( + StorageService storageService, + SimpMessagingTemplate template, + FileImporterProperties fileImporterProps, + FileTopics fileTopics, + JsonTopics jsonTopics, + RawEncodedJsonTopics rawEncodedJsonTopics, + OdeKafkaProperties odeKafkaProperties) { + super(); + this.storageService = storageService; + + ExecutorService threadPool = Executors.newCachedThreadPool(); + + // Create the importers that watch folders for new/modified files + threadPool.submit( + new ImporterDirectoryWatcher(fileImporterProps, + odeKafkaProperties, + jsonTopics, + ImporterDirectoryWatcher.ImporterFileType.LOG_FILE, + rawEncodedJsonTopics) + ); + + // Create unfiltered exporters + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getBsm(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getTim(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getSpat(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getMap(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getSsm(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getSrm(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getDriverAlert(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getUnfilteredOutput(), template, jsonTopics.getTimBroadcast(), odeKafkaProperties.getBrokers())); + + // Create filtered exporters + threadPool.submit(new StompStringExporter(fileTopics.getFilteredOutput(), template, jsonTopics.getBsmFiltered(), odeKafkaProperties.getBrokers())); + threadPool.submit(new StompStringExporter(fileTopics.getFilteredOutput(), template, jsonTopics.getTimFiltered(), odeKafkaProperties.getBrokers())); + } + + @PostMapping("/upload/{type}") + public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file, @PathVariable("type") String type) { + + log.debug("File received at endpoint: /upload/{}, name={}", type, file.getOriginalFilename()); + try { + storageService.store(file, type); + } catch (Exception e) { + log.error("File storage error", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("{\"Error\": \"File storage error.\"}"); + // do not return exception, XSS vulnerable + } + + return ResponseEntity.status(HttpStatus.OK).body("{\"Success\": \"True\"}"); + } + + @ExceptionHandler(StorageFileNotFoundException.class) + public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) { + return ResponseEntity.notFound().build(); + } } diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index 63d2f31fc..b2d87053e 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -5,6 +5,15 @@ spring: max-request-size: 1MB ode: host-ip: ${DOCKER_HOST_IP} + verbose-json: false + plugins-locations: "plugins" + output-schema-version: 7 + security-svcs-port: 8090 + security-svcs-signature-endpoint: "sign" + rsu: + srm-slots: 100 + username: ${RSU_USERNAME} + password: ${RSU_PASSWORD} kafka: brokers: ${DOCKER_HOST_IP}:9092 producer-type: sync @@ -13,3 +22,89 @@ ode: - "topic.OdeBsmTxPojo" - "topic.OdeBsmDuringEventPojo" - "topic.OdeTimBroadcastPojo" + topics: + asn1: + decoder-input: "topic.Asn1DecoderInput" + decoder-output: "topic.Asn1DecoderOutput" + encoder-input: "topic.Asn1EncoderInput" + encoder-output: "topic.Asn1EncoderOutput" + json: + bsm: "topic.OdeBsmJson" + map: "topic.OdeMapJson" + psm: "topic.OdePsmJson" + spat: "topic.OdeSpatJson" + srm: "topic.OdeSrmJson" + ssm: "topic.OdeSsmJson" + tim: "topic.OdeTimJson" + driver-alert: "topic.OdeDriverAlertJson" + tim-broadcast: "topic.OdeTimBroadcastJson" + bsm-filtered: "topic.FilteredOdeBsmJson" + spat-filtered: "topic.FilteredOdeSpatJson" + tim-filtered: "topic.FilteredOdeTimJson" + tim-tmc-filtered: "topic.OdeTimJsonTMCFiltered" + tim-cert-expiration: "topic.OdeTIMCertExpirationTimeJson" + dn-message: "topic.OdeDNMsgJson" + rx-tim: "topic.OdeTimRxJson" + rx-spat: "topic.OdeSpatRxJson" + j2735-tim-broadcast: "topic.J2735TimBroadcastJson" + pojo: + bsm: "topic.OdeBsmPojo" + spat: "topic.OdeSpatPojo" + ssm: "topic.OdeSsmPojo" + tim-broadcast: "topic.OdeTimBroadcastPojo" + bsm-during-event: "topic.OdeBsmDuringEventPojo" + rx-bsm: "topic.OdeBsmRxPojo" + rx-spat: "topic.OdeSpatRxPojo" + tx-bsm: "topic.OdeBsmTxPojo" + tx-map: "topic.OdeMapTxPojo" + tx-psm: "topic.OdePsmTxPojo" + tx-spat: "topic.OdeSpatTxPojo" + tx-srm: "topic.OdeSrmTxPojo" + raw-encoded-json: + bsm: "topic.OdeRawEncodedBSMJson" + map: "topic.OdeRawEncodedMAPJson" + psm: "topic.OdeRawEncodedPSMJson" + spat: "topic.OdeRawEncodedSPATJson" + srm: "topic.OdeRawEncodedSRMJson" + ssm: "topic.OdeRawEncodedSSMJson" + tim: "topic.OdeRawEncodedTIMJson" + sdx-depositor: + input: "topic.SDWDepositorInput" + file: + filtered-output: "/topic/filtered_messages" + unfiltered-output: "/topic/unfiltered_messages" + receivers: + generic: + buffer-size: 2000 + receiver-port: 44990 + bsm: + buffer-size: 500 + receiver-port: 46800 + map: + buffer-size: 2048 + receiver-port: 44920 + psm: + buffer-size: 500 + receiver-port: 44940 + spat: + buffer-size: 500 + receiver-port: 44910 + srm: + buffer-size: 500 + receiver-port: 44930 + ssm: + buffer-size: 500 + receiver-port: 44900 + tim: + buffer-size: 500 + receiver-port: 47900 + file-importer: + buffer-size: 500 + backup-dir: "backup" + failed-dir: "failed" + time-period: 5 + upload-location-root: "uploads" + obu-log-upload-location: "bsmlog" + tim-ingest-monitoring: + tracking-enabled: ${ODE_TIM_INGEST_MONITORING_ENABLED} + interval: ${ODE_TIM_INGEST_MONITORING_INTERVAL} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index e8d699966..2e8742f03 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -1,212 +1,71 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ package us.dot.its.jpo.ode; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.info.BuildProperties; -import org.springframework.core.env.Environment; - -import mockit.Capturing; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Tested; -import us.dot.its.jpo.ode.util.CommonUtils; - +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.rsu.RSUProperties; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@Import({BuildProperties.class}) +@EnableConfigurationProperties(value = {OdeProperties.class, RSUProperties.class, org.springframework.boot.info.BuildProperties.class}) class OdePropertiesTest { - @Tested - OdeProperties testOdeProperties; - @Injectable - Environment mockEnv; - @Injectable - BuildProperties mockBuildProperties; - - @Capturing - CommonUtils capturingCommonUtils; - - @Test - void testInit() { - new Expectations() { - { - } - }; - try { - new OdeProperties(); - } catch (Exception e) { - fail("Unexpected exception: " + e); - } - } - - @Test - void testSettersAndGetters() { - - String testPluginsLocations = "testpluginsLocations123456"; - String testUploadLocationObuLog = "testuploadLocationObuLog123456"; - String testUploadLocationRoot = "testUploadLocationRoot123456"; - int testMessagesUntilTrustReestablished = 17; - String testCaCertPath = "testCaCertPath"; - String testSelfCertPath = "testSelfCertPath"; - String testSelfPrivateKeyReconstructionFilePath = "testSelfPrivateKeyReconstructionFilePath"; - String testSelfSigningPrivateKeyFilePath = "testSelfSigningPrivateKeyFilePath"; - String testKafkaTopicBsmFilteredJson = "testKafkaTopicBsmFilteredJson"; - boolean testVerboseJson = true; - int testRsuSrmSlots = 22; - int testTrustRetries = 23; - String testKafkaTopicOdeBsmPojo = "testKafkaTopicOdeBsmPojo"; - String testKafkaTopicOdeBsmJson = "testKafkaTopicOdeBsmJson"; - int testImportProcessorBufferSize = 83; - - String testKafkaTopicAsn1DecoderInput = "testKafkaTopicAsn1DecoderInput"; - String testKafkaTopicAsn1DecoderOutput = "testKafkaTopicAsn1DecoderOutput"; - String testKafkaTopicAsn1EncoderInput = "testKafkaTopicAsn1EncoderInput"; - String testKafkaTopicAsn1EncoderOutput = "testKafkaTopicAsn1EncoderOutput"; - String testKafkaTopicOdeDNMsgJson = "testKafkaTopicOdeDNMsgJson"; - String testKafkaTopicOdeTimJson = "testKafkaTopicOdeTimJson"; - String testKafkaTopicOdeTimJsonTMCFiltered = "testKafkaTopicOdeTimJsonTMCFiltered"; - String testKafkaTopicOdeBsmDuringEventPojo = "testKafkaTopicOdeBsmDuringEventPojo"; - String testKafkaTopicOdeBsmRxPojo = "testKafkaTopicOdeBsmRxPojo"; - String testKafkaTopicOdeBsmTxPojo = "testKafkaTopicOdeBsmTxPojo"; - String testKafkaTopicOdeTimRxJson = "testKafkaTopicOdeTimRxJson"; - String testKafkaTopicOdeTimBroadcastPojo = "testKafkaTopicOdeTimBroadcastPojo"; - String testKafkaTopicOdeTimBroadcastJson = "testKafkaTopicOdeTimBroadcastJson"; - String testKafkaTopicJ2735TimBroadcastJson = "testKafkaTopicJ2735TimBroadcastJson"; - String testKafkaTopicFilteredOdeTimJson = "testKafkaTopicFilteredOdeTimJson"; - String testKafkaTopicDriverAlertJson = "testKafkaTopicDriverAlertJson"; - - Integer testFileWatcherPeriod = 5; - String testSecuritySvcsSignatureUri = "testSecuritySvcsSignatureUri"; - String testRsuUsername = "testRsuUsername"; - String testRsuPassword = "testRsuPassword"; - - testOdeProperties.setHostIP("test-host"); - testOdeProperties.setEnv(mockEnv); - testOdeProperties.setEnvironment(mockEnv); - testOdeProperties.setPluginsLocations(testPluginsLocations); - testOdeProperties.setUploadLocationObuLog(testUploadLocationObuLog); - testOdeProperties.setUploadLocationRoot(testUploadLocationRoot); - testOdeProperties.setMessagesUntilTrustReestablished(testMessagesUntilTrustReestablished); - testOdeProperties.setCaCertPath(testCaCertPath); - testOdeProperties.setSelfCertPath(testSelfCertPath); - testOdeProperties.setSelfPrivateKeyReconstructionFilePath(testSelfPrivateKeyReconstructionFilePath); - testOdeProperties.setSelfSigningPrivateKeyFilePath(testSelfSigningPrivateKeyFilePath); - testOdeProperties.setKafkaTopicFilteredOdeBsmJson(testKafkaTopicBsmFilteredJson); - testOdeProperties.setVerboseJson(testVerboseJson); - testOdeProperties.setRsuSrmSlots(testRsuSrmSlots); - testOdeProperties.setTrustRetries(testTrustRetries); - testOdeProperties.setKafkaTopicOdeBsmPojo(testKafkaTopicOdeBsmPojo); - testOdeProperties.setKafkaTopicOdeBsmJson(testKafkaTopicOdeBsmJson); - testOdeProperties.setImportProcessorBufferSize(testImportProcessorBufferSize); - - testOdeProperties.setKafkaTopicAsn1DecoderInput(testKafkaTopicAsn1DecoderInput); - testOdeProperties.setKafkaTopicAsn1DecoderOutput(testKafkaTopicAsn1DecoderOutput); - testOdeProperties.setKafkaTopicAsn1EncoderInput(testKafkaTopicAsn1EncoderInput); - testOdeProperties.setKafkaTopicAsn1EncoderOutput(testKafkaTopicAsn1EncoderOutput); - testOdeProperties.setKafkaTopicOdeDNMsgJson(testKafkaTopicOdeDNMsgJson); - testOdeProperties.setKafkaTopicOdeTimJson(testKafkaTopicOdeTimJson); - testOdeProperties.setKafkaTopicOdeTimJsonTMCFiltered(testKafkaTopicOdeTimJsonTMCFiltered); - testOdeProperties.setKafkaTopicOdeBsmDuringEventPojo(testKafkaTopicOdeBsmDuringEventPojo); - testOdeProperties.setKafkaTopicOdeBsmRxPojo(testKafkaTopicOdeBsmRxPojo); - testOdeProperties.setKafkaTopicOdeBsmTxPojo(testKafkaTopicOdeBsmTxPojo); - testOdeProperties.setKafkaTopicOdeTimRxJson(testKafkaTopicOdeTimRxJson); - testOdeProperties.setKafkaTopicOdeTimBroadcastPojo(testKafkaTopicOdeTimBroadcastPojo); - testOdeProperties.setKafkaTopicOdeTimBroadcastJson(testKafkaTopicOdeTimBroadcastJson); - testOdeProperties.setKafkaTopicJ2735TimBroadcastJson(testKafkaTopicJ2735TimBroadcastJson); - testOdeProperties.setKafkaTopicFilteredOdeTimJson(testKafkaTopicFilteredOdeTimJson); - testOdeProperties.setKafkaTopicDriverAlertJson(testKafkaTopicDriverAlertJson); - - testOdeProperties.setFileWatcherPeriod(testFileWatcherPeriod); - testOdeProperties.setSecuritySvcsSignatureUri(testSecuritySvcsSignatureUri); - testOdeProperties.setRsuUsername(testRsuUsername); - testOdeProperties.setRsuPassword(testRsuPassword); - - assertEquals("test-host", testOdeProperties.getHostIP()); - assertEquals("Incorrect testEnv", mockEnv, testOdeProperties.getEnv()); - assertEquals("Incorrect testpluginsLocations", testPluginsLocations, - testOdeProperties.getPluginsLocations()); - assertEquals("Incorrect testUploadLocationObuLog", testUploadLocationObuLog, - testOdeProperties.getUploadLocationObuLog()); - assertEquals("Incorrect testUploadLocationRoot", testUploadLocationRoot, - testOdeProperties.getUploadLocationRoot()); - assertEquals("Incorrect testMessagesUntilTrustReestablished", testMessagesUntilTrustReestablished, - testOdeProperties.getMessagesUntilTrustReestablished()); - assertEquals("Incorrect testCaCertPath", testCaCertPath, testOdeProperties.getCaCertPath()); - assertEquals("Incorrect testSelfCertPath", testSelfCertPath, testOdeProperties.getSelfCertPath()); - assertEquals("Incorrect testSelfPrivateKeyReconstructionFilePath", testSelfPrivateKeyReconstructionFilePath, - testOdeProperties.getSelfPrivateKeyReconstructionFilePath()); - assertEquals("Incorrect testSelfSigningPrivateKeyFilePath", testSelfSigningPrivateKeyFilePath, - testOdeProperties.getSelfSigningPrivateKeyFilePath()); - assertEquals("Incorrect testKafkaTopicBsmFilteredJson", testKafkaTopicBsmFilteredJson, - testOdeProperties.getKafkaTopicFilteredOdeBsmJson()); - assertEquals("Incorrect testVerboseJson", testVerboseJson, testOdeProperties.getVerboseJson()); - assertEquals("Incorrect testRsuSrmSlots", testRsuSrmSlots, testOdeProperties.getRsuSrmSlots()); - assertEquals("Incorrect testTrustRetries", testTrustRetries, testOdeProperties.getTrustRetries()); - assertEquals("Incorrect testKafkaTopicOdeBsmPojo", testKafkaTopicOdeBsmPojo, - testOdeProperties.getKafkaTopicOdeBsmPojo()); - assertEquals("Incorrect testKafkaTopicOdeBsmJson", testKafkaTopicOdeBsmJson, - testOdeProperties.getKafkaTopicOdeBsmJson()); - assertEquals("Incorrect testImportProcessorBufferSize", testImportProcessorBufferSize, - testOdeProperties.getImportProcessorBufferSize()); - - assertEquals("Incorrect testKafkaTopicAsn1DecoderInput", testKafkaTopicAsn1DecoderInput, - testOdeProperties.getKafkaTopicAsn1DecoderInput()); - assertEquals("Incorrect testKafkaTopicAsn1DecoderOutput", testKafkaTopicAsn1DecoderOutput, - testOdeProperties.getKafkaTopicAsn1DecoderOutput()); - assertEquals("Incorrect testKafkaTopicAsn1EncoderInput", testKafkaTopicAsn1EncoderInput, - testOdeProperties.getKafkaTopicAsn1EncoderInput()); - assertEquals("Incorrect testKafkaTopicAsn1EncoderOutput", testKafkaTopicAsn1EncoderOutput, - testOdeProperties.getKafkaTopicAsn1EncoderOutput()); - assertEquals("Incorrect testKafkaTopicOdeDNMsgJson", testKafkaTopicOdeDNMsgJson, - testOdeProperties.getKafkaTopicOdeDNMsgJson()); - assertEquals("Incorrect testKafkaTopicOdeTimJson", testKafkaTopicOdeTimJson, - testOdeProperties.getKafkaTopicOdeTimJson()); - assertEquals("Incorrect testKafkaTopicOdeTimJsonTMCFiltered", testKafkaTopicOdeTimJsonTMCFiltered, - testOdeProperties.getKafkaTopicOdeTimJsonTMCFiltered()); - assertEquals("Incorrect testKafkaTopicOdeBsmDuringEventPojo", testKafkaTopicOdeBsmDuringEventPojo, - testOdeProperties.getKafkaTopicOdeBsmDuringEventPojo()); - assertEquals("Incorrect testKafkaTopicOdeBsmRxPojo", testKafkaTopicOdeBsmRxPojo, - testOdeProperties.getKafkaTopicOdeBsmRxPojo()); - assertEquals("Incorrect testKafkaTopicOdeBsmTxPojo", testKafkaTopicOdeBsmTxPojo, - testOdeProperties.getKafkaTopicOdeBsmTxPojo()); - assertEquals("Incorrect testKafkaTopicOdeTimRxJson", testKafkaTopicOdeTimRxJson, - testOdeProperties.getKafkaTopicOdeTimRxJson()); - assertEquals("Incorrect testKafkaTopicOdeTimBroadcastPojo", testKafkaTopicOdeTimBroadcastPojo, - testOdeProperties.getKafkaTopicOdeTimBroadcastPojo()); - assertEquals("Incorrect testKafkaTopicOdeTimBroadcastJson", testKafkaTopicOdeTimBroadcastJson, - testOdeProperties.getKafkaTopicOdeTimBroadcastJson()); - assertEquals("Incorrect testKafkaTopicJ2735TimBroadcastJson", testKafkaTopicJ2735TimBroadcastJson, - testOdeProperties.getKafkaTopicJ2735TimBroadcastJson()); - assertEquals("Incorrect testKafkaTopicFilteredOdeTimJson", testKafkaTopicFilteredOdeTimJson, - testOdeProperties.getKafkaTopicFilteredOdeTimJson()); - assertEquals("Incorrect testKafkaTopicDriverAlertJson", testKafkaTopicDriverAlertJson, - testOdeProperties.getKafkaTopicDriverAlertJson()); - - assertEquals("Incorrect testFileWatcherPeriod", testFileWatcherPeriod, - testOdeProperties.getFileWatcherPeriod()); - assertEquals("Incorrect testSecuritySvcsSignatureUri", testSecuritySvcsSignatureUri, - testOdeProperties.getSecuritySvcsSignatureUri()); - assertEquals("Incorrect testRsuUsername", testRsuUsername, testOdeProperties.getRsuUsername()); - assertEquals("Incorrect RsuPassword", testRsuPassword, testOdeProperties.getRsuPassword()); - - testOdeProperties.getProperty("testProperty"); - testOdeProperties.getProperty("testProperty", 5); - testOdeProperties.getProperty("testProperty", "testDefaultValue"); - testOdeProperties.getUploadLocations(); - } - -} + @Autowired + OdeProperties testOdeProperties; + + @Test + void testOutputSchemaVersion() { + assertEquals(7, testOdeProperties.getOutputSchemaVersion()); + } + + @Test + void testPluginsLocations() { + assertEquals("plugins", testOdeProperties.getPluginsLocations()); + } + + @Test + void testHostIP() { + assertEquals("test-host", testOdeProperties.getHostIP()); + } + + @Test + void testVerboseJson() { + assertFalse(testOdeProperties.isVerboseJson()); + } + + @Test + void testSecuritySvcsSignatureUri() { + String expected = "http://" + testOdeProperties.getHostIP() + ":" + testOdeProperties.getSecuritySvcsPort() + "/" + + testOdeProperties.getSecuritySvcsSignatureEndpoint(); + assertEquals(expected, testOdeProperties.getSecuritySvcsSignatureUri()); + } + + @Test + void testSecuritySvcsPort() { + assertEquals(8090, testOdeProperties.getSecuritySvcsPort()); + } + + @Test + void testSecuritySvcsSignatureEndpoint() { + assertEquals("sign", testOdeProperties.getSecuritySvcsSignatureEndpoint()); + } + + @Test + void testRsuProperties() { + RSUProperties rsuProperties = testOdeProperties.rsuProperties(); + + assertEquals(100, rsuProperties.getSrmSlots()); + assertEquals("test-username", rsuProperties.getUsername()); + assertEquals("test-password", rsuProperties.getPassword()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java index c757d22c5..4582344fd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java @@ -5,35 +5,33 @@ import org.apache.kafka.streams.Topology; import org.apache.kafka.streams.state.ReadOnlyKeyValueStore; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; - -public class OdeTimJsonTopologyTest { +class OdeTimJsonTopologyTest { private OdeTimJsonTopology odeTimJsonTopology; private KafkaStreams mockStreams; private ReadOnlyKeyValueStore mockStore; - private OdeProperties mockOdeProps; private OdeKafkaProperties mockOdeKafkaProps; @BeforeEach - public void setUp() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - mockOdeProps = mock(OdeProperties.class); + void setUp() throws SecurityException, IllegalArgumentException { mockOdeKafkaProps = mock(OdeKafkaProperties.class); - odeTimJsonTopology = new OdeTimJsonTopology(mockOdeProps, mockOdeKafkaProps); + odeTimJsonTopology = new OdeTimJsonTopology(mockOdeKafkaProps); mockStreams = mock(KafkaStreams.class); mockStore = mock(ReadOnlyKeyValueStore.class); @@ -41,12 +39,12 @@ public void setUp() throws NoSuchFieldException, SecurityException, IllegalArgum } @AfterEach - public void tearDown() { + void tearDown() { OdeTimJsonTopology.streams = null; } @Test - public void testStart() { + void testStart() { when(mockStreams.state()).thenReturn(KafkaStreams.State.NOT_RUNNING); doNothing().when(mockStreams).start(); @@ -56,7 +54,7 @@ public void testStart() { } @Test - public void testStartWhenAlreadyRunning() { + void testStartWhenAlreadyRunning() { when(mockStreams.state()).thenReturn(KafkaStreams.State.RUNNING); IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { @@ -67,7 +65,7 @@ public void testStartWhenAlreadyRunning() { } @Test - public void testStop() { + void testStop() { doNothing().when(mockStreams).close(); odeTimJsonTopology.stop(); @@ -76,27 +74,27 @@ public void testStop() { } @Test - public void testIsRunning() { + void testIsRunning() { when(mockStreams.state()).thenReturn(KafkaStreams.State.RUNNING); assertTrue(odeTimJsonTopology.isRunning()); } @Test - public void testIsNotRunning() { + void testIsNotRunning() { when(mockStreams.state()).thenReturn(KafkaStreams.State.NOT_RUNNING); assertFalse(odeTimJsonTopology.isRunning()); } @Test - public void testBuildTopology() { + void testBuildTopology() { Topology topology = odeTimJsonTopology.buildTopology(); assertNotNull(topology); } @Test - public void testQuery() { + void testQuery() { String uuid = "test-uuid"; String expectedValue = "test-value"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java index b483d67dc..5c0832a72 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java @@ -52,6 +52,6 @@ public void shouldPublishTwice() { } }; - testMessagePublisher.publish(mockOdeBsmData, "topic"); + testMessagePublisher.publish("topic", mockOdeBsmData); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java index c77e1ceed..86607c9a6 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeDataPublisherTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,45 +15,42 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.junit.jupiter.api.Test; - import mockit.Capturing; import mockit.Expectations; -import mockit.Injectable; import mockit.Mocked; import mockit.Tested; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class OdeDataPublisherTest { - - @Tested - OdeDataPublisher testMessagePublisher; - @Injectable - OdeProperties testOdeProperties; - @Injectable - OdeKafkaProperties injectableOdeKafkaProperties; - @Injectable - String testSerializer; - @Mocked - OdeBsmData mockOdeBsmData; - - @Capturing - MessageProducer capturingMessageProducer; - - @Test - public void shouldPublishTwice() { - - new Expectations() { - { - capturingMessageProducer.send(anyString, null, (OdeData) any); - times = 1; - } - }; - - testMessagePublisher.publish(mockOdeBsmData, "topic"); - } +import java.util.Set; + + +class OdeDataPublisherTest { + + @Tested + OdeDataPublisher testMessagePublisher = new OdeDataPublisher("sync", + "localhost:9093", + Set.of(), + "us.dot.its.jpo.ode.wrapper.serdes.OdeBsmSerializer"); + @Mocked + OdeBsmData mockOdeBsmData; + + + @Capturing + MessageProducer capturingMessageProducer; + + @Test + void shouldPublishOnce() { + + new Expectations() { + { + capturingMessageProducer.send(anyString, null, (OdeData) any); + times = 1; + } + }; + + testMessagePublisher.publish("topic", mockOdeBsmData); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java index 0fd875644..945e168a2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeStringPublisherTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,40 +15,32 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.junit.jupiter.api.Test; - import mockit.Capturing; import mockit.Expectations; -import mockit.Injectable; import mockit.Tested; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class OdeStringPublisherTest { - - @Tested - OdeStringPublisher testOdeStringPublisher; +import java.util.Set; - @Injectable - OdeProperties injectableOdeProperties; +class OdeStringPublisherTest { - @Injectable - OdeKafkaProperties injectableOdeKafkaProperties; + @Tested + OdeStringPublisher testOdeStringPublisher = new OdeStringPublisher("localhost:9093", "sync", Set.of("disabledTopic")); - @Capturing - MessageProducer capturingMessageProducer; + @Capturing + MessageProducer capturingMessageProducer; - @Test - public void publishShouldCallMessageProducer() { - new Expectations() { - { - capturingMessageProducer.send(anyString, null, anyString); - times = 1; - } - }; + @Test + void publishShouldCallMessageProducer() { + new Expectations() { + { + capturingMessageProducer.send(anyString, null, anyString); + times = 1; + } + }; - testOdeStringPublisher.publish(new OdeData(), "testTopic"); - } + testOdeStringPublisher.publish("testTopic", new OdeData()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java index 083973e92..e42fa2a9f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,370 +15,372 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder.stream; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThrows; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.util.List; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; import mockit.Tested; -import us.dot.its.jpo.ode.OdeProperties; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher.LogFileToAsn1CodecPublisherException; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; import us.dot.its.jpo.ode.importer.parser.FileParser.ParserStatus; import us.dot.its.jpo.ode.importer.parser.LogFileParser; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.util.DateTimeUtils; -public class LogFileToAsn1CodecPublisherTest { - - private static final String GZ = ".gz"; - private static String schemaVersion = "7"; - - @Tested - LogFileToAsn1CodecPublisher testLogFileToAsn1CodecPublisher; - - @Injectable - StringPublisher injectableStringPublisher; - - @BeforeAll - public static void setupClass() { - OdeMsgMetadata.setStaticSchemaVersion(OdeProperties.OUTPUT_SCHEMA_VERSION); - schemaVersion = Integer.toString(OdeProperties.OUTPUT_SCHEMA_VERSION); - } - - @Test - public void testPublishInit(@Mocked LogFileParser mockLogFileParser) throws Exception { - new Expectations() { - { - LogFileParser.factory(anyString); - result = mockLogFileParser; - - mockLogFileParser.parseFile((BufferedInputStream) any, anyString); - result = ParserStatus.INIT; - } - }; - - List dataList = testLogFileToAsn1CodecPublisher.publish( - new BufferedInputStream(new ByteArrayInputStream(new byte[0])), - "fileName", ImporterFileType.LOG_FILE); - - assertTrue(dataList.isEmpty()); - } - - @Test - public void testPublishEOF(@Mocked LogFileParser mockLogFileParser) throws Exception { - new Expectations() { - { - LogFileParser.factory(anyString); - result = mockLogFileParser; - - mockLogFileParser.parseFile((BufferedInputStream) any, anyString); - result = ParserStatus.EOF; - } - }; - - List dataList = testLogFileToAsn1CodecPublisher.publish( - new BufferedInputStream(new ByteArrayInputStream(new byte[0])), - "fileName", ImporterFileType.LOG_FILE); - - assertTrue(dataList.isEmpty()); - } - - @Test - public void testPublishThrowsIllegalArgumentException() throws Exception { - // If the filename does not follow expected filename pattern, - // IllegalArgumentException should be thrown - assertThrows(IllegalArgumentException.class, () -> { - // If the filename does not follow expected filename pattern, - // IllegalArgumentException should be thrown - testLogFileToAsn1CodecPublisher.publish(new BufferedInputStream(new ByteArrayInputStream(new byte[0])), - "fileName", ImporterFileType.LOG_FILE); - fail("Expected an IllegalArgumentException to be thrown"); - }); - } - - @Test - public void testPublishThrowsLogFileToAsn1CodecPublisherException(@Mocked LogFileParser mockLogFileParser) - throws Exception { - assertThrows(LogFileToAsn1CodecPublisherException.class, () -> { +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class LogFileToAsn1CodecPublisherTest { + + private static final String GZ = ".gz"; + private static final String schemaVersion = "7"; + + @Tested + LogFileToAsn1CodecPublisher testLogFileToAsn1CodecPublisher; + + @Injectable + StringPublisher injectableStringPublisher; + + @Injectable + JsonTopics injectableJsonTopics; + + @Injectable + RawEncodedJsonTopics injectableRawEncodedJsonTopics; + + + @BeforeAll + public static void setupClass() { + OdeMsgMetadata.setStaticSchemaVersion(Integer.parseInt(schemaVersion)); + } + + @Test + void testPublishInit(@Mocked LogFileParser mockLogFileParser) throws Exception { + new Expectations() { + { + LogFileParser.factory(anyString); + result = mockLogFileParser; + + mockLogFileParser.parseFile((BufferedInputStream) any, anyString); + result = ParserStatus.INIT; + } + }; + + List dataList = testLogFileToAsn1CodecPublisher.publish( + new BufferedInputStream(new ByteArrayInputStream(new byte[0])), + "fileName", ImporterFileType.LOG_FILE); + + assertTrue(dataList.isEmpty()); + } + + @Test + void testPublishEOF(@Mocked LogFileParser mockLogFileParser) throws Exception { + new Expectations() { + { + LogFileParser.factory(anyString); + result = mockLogFileParser; + + mockLogFileParser.parseFile((BufferedInputStream) any, anyString); + result = ParserStatus.EOF; + } + }; + + List dataList = testLogFileToAsn1CodecPublisher.publish( + new BufferedInputStream(new ByteArrayInputStream(new byte[0])), + "fileName", ImporterFileType.LOG_FILE); + + assertTrue(dataList.isEmpty()); + } + + @Test + void testPublishThrowsIllegalArgumentException() { + // If the filename does not follow expected filename pattern, + // IllegalArgumentException should be thrown + assertThrows(IllegalArgumentException.class, () -> { + // If the filename does not follow expected filename pattern, + // IllegalArgumentException should be thrown + testLogFileToAsn1CodecPublisher.publish(new BufferedInputStream(new ByteArrayInputStream(new byte[0])), + "fileName", ImporterFileType.LOG_FILE); + fail("Expected an IllegalArgumentException to be thrown"); + }); + } + + @Test + void testPublishThrowsLogFileToAsn1CodecPublisherException(@Mocked LogFileParser mockLogFileParser) { + assertThrows(LogFileToAsn1CodecPublisherException.class, () -> { new Expectations() { - { - LogFileParser.factory(anyString); - result = mockLogFileParser; - - /* - * If the embedded parser fails to parse a log file header, it may throw an - * exception - * which is then caught by the parser and re-thrown as - * LogFileToAsn1CodecPublisherException. - * This mocked object will simulate that eventuality. - */ - mockLogFileParser.parseFile((BufferedInputStream) any, anyString); - result = new LogFileToAsn1CodecPublisherException(anyString, (Exception) any); - } + { + LogFileParser.factory(anyString); + result = mockLogFileParser; + + /* + * If the embedded parser fails to parse a log file header, it may throw an + * exception + * which is then caught by the parser and re-thrown as + * LogFileToAsn1CodecPublisherException. + * This mocked object will simulate that eventuality. + */ + mockLogFileParser.parseFile((BufferedInputStream) any, anyString); + result = new LogFileToAsn1CodecPublisherException(anyString, (Exception) any); + } }; - + testLogFileToAsn1CodecPublisher.publish(new BufferedInputStream(new ByteArrayInputStream(new byte[0])), - "fileName", ImporterFileType.LOG_FILE); + "fileName", ImporterFileType.LOG_FILE); fail("Expected an LogFileToAsn1CodecPublisherException to be thrown"); - }); - } - - @Test - public void testPublishDecodeFailure(@Mocked LogFileParser mockLogFileParser) throws Exception { - new Expectations() { - { - LogFileParser.factory(anyString); - result = mockLogFileParser; - - mockLogFileParser.parseFile((BufferedInputStream) any, anyString); - result = ParserStatus.ERROR; - } - }; - - List dataList = testLogFileToAsn1CodecPublisher.publish( - new BufferedInputStream(new ByteArrayInputStream(new byte[0])), - "fileName", ImporterFileType.LOG_FILE); - - assertTrue(dataList.isEmpty()); - } - - @Test - public void testPublishBsmTxLogFile() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x00, // 1. direction - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation - (byte) 0x04, (byte) 0x00, // 2.3 speed - (byte) 0x09, (byte) 0x27, // 2.4 heading - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 4. mSec - (byte) 0x00, // 5. securityResultCode - (byte) 0x06, (byte) 0x00, // 6.0 payloadLength - // 6.1 payload - (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 - }; - - String filename = RecordType.bsmTx.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - String asn1String = data.getMetadata().getAsn1(); - var expected = String.format("{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"bsmTx.gz\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); - assertEquals(expected, data.toJson()); - } - } - - @Test - public void testPublishDistressNotificationLogFile() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 1.1 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 1.2 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 1.3 elevation - (byte) 0x04, (byte) 0x00, // 1.4 speed - (byte) 0x09, (byte) 0x27, // 1.5 heading - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 3. mSec - (byte) 0x00, // 4. securityResultCode - (byte) 0x06, (byte) 0x00, // 5.1 payloadLength - // 5.2 payload - (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x40, (byte) 0x03, (byte) 0x80 - }; - - String filename = RecordType.dnMsg.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - var expected = String.format("{\"metadata\":{\"logFileName\":\"dnMsg.gz\",\"recordType\":\"dnMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"encodings\":[{\"elementName\":\"root\",\"elementType\":\"Ieee1609Dot2Data\",\"encodingRule\":\"COER\"},{\"elementName\":\"unsecuredData\",\"elementType\":\"MessageFrame\",\"encodingRule\":\"UPER\"}],\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"038100400380\"}}}", schemaVersion); - } - } - - @Test - public void testPublishDriverAlertLogFile() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 1.0 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 1.1 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 1.2 elevation - (byte) 0x04, (byte) 0x00, // 1.3 speed - (byte) 0x09, (byte) 0x27, // 1.4 heading - - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 3. mSec - (byte) 0x11, (byte) 0x00, // 4.0 payloadLength - // 4.1 payload - 'T', 'e', 's', 't', ' ', 'D', 'r', 'i', 'v', 'e', 'r', ' ', 'A', 'l', 'e', 'r', 't' - }; - - String filename = RecordType.driverAlert.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - var expected = String.format("{\"metadata\":{\"logFileName\":\"driverAlert.gz\",\"recordType\":\"driverAlert\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeDriverAlertPayload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false},\"payload\":{\"alert\":\"Test Driver Alert\"}}", schemaVersion); - assertEquals(expected, data.toJson()); - } - } - - @Test - public void testPublishRxMsgTIMLogFile() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x01, // 1. RxSource = SAT - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation - (byte) 0x04, (byte) 0x00, // 2.3 speed - (byte) 0x09, (byte) 0x27, // 2.4 heading - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 4. mSec - (byte) 0x00, // 5. securityResultCode - (byte) 0x06, (byte) 0x00, // 6.0 payloadLength - // 6.1 payload - (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 - }; - - String filename = RecordType.rxMsg.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - String asn1String = data.getMetadata().getAsn1(); - var expected = String.format("{\"metadata\":{\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"SAT\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"TMC_VIA_SAT\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); - assertEquals(expected, data.toJson()); - } - } - - @Test - public void testPublishRxMsgBSMLogFile() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x02, // 1. RxSource = RV - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation - (byte) 0x04, (byte) 0x00, // 2.3 speed - (byte) 0x09, (byte) 0x27, // 2.4 heading - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 4. mSec - (byte) 0x00, // 5. securityResultCode - (byte) 0x06, (byte) 0x00, // 6.0 payloadLength - // 6.1 payload - (byte) 0x11, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 - }; - - String filename = RecordType.rxMsg.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - String asn1String = data.getMetadata().getAsn1(); - var expected = String.format("{\"metadata\":{\"bsmSource\":\"RV\",\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"RV\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); - assertEquals(expected, data.toJson()); - } - } - - @Test - public void testPublishNonLearLogFile() throws Exception { - - String filename = RecordType.rxMsg.name() + GZ; - - String jsonData = "{\"fakeJsonKey\":\"fakeJsonValue\""; - byte[] buf = jsonData.getBytes(); - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - /* - * This call to publish method does not actually try to parse the data. It - * short-circuits the parsing because - * currently we dont' support JSON input records. We may in the future. - */ - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.JSON_FILE); - - assertTrue(dataList.isEmpty()); - } - - @Test - public void testPublishRxMsgBSMLogFileNewLine() throws Exception { - - byte[] buf = new byte[] { - (byte) 0x02, // 1. RxSource = RV - (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude - (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude - (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation - (byte) 0x04, (byte) 0x00, // 2.3 speed - (byte) 0x09, (byte) 0x27, // 2.4 heading - (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec - (byte) 0x8f, (byte) 0x01, // 4. mSec - (byte) 0x00, // 5. securityResultCode - (byte) 0x06, (byte) 0x00, // 6.0 payloadLength - // 6.1 payload - (byte) 0x11, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80, - (byte) 0x0a - }; - - String filename = RecordType.rxMsg.name() + GZ; - - BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); - - List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); - - for (OdeData data : dataList) { - assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), - DateTimeUtils.nowZDT()) > 0); - data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); - data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); - String asn1String = data.getMetadata().getAsn1(); - var expected = String.format("{\"metadata\":{\"bsmSource\":\"RV\",\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"RV\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); - assertEquals(expected, data.toJson()); - } - } + }); + } + + @Test + void testPublishDecodeFailure(@Mocked LogFileParser mockLogFileParser) throws Exception { + new Expectations() { + { + LogFileParser.factory(anyString); + result = mockLogFileParser; + + mockLogFileParser.parseFile((BufferedInputStream) any, anyString); + result = ParserStatus.ERROR; + } + }; + + List dataList = testLogFileToAsn1CodecPublisher.publish( + new BufferedInputStream(new ByteArrayInputStream(new byte[0])), + "fileName", ImporterFileType.LOG_FILE); + + assertTrue(dataList.isEmpty()); + } + + @Test + void testPublishBsmTxLogFile() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x00, // 1. direction + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation + (byte) 0x04, (byte) 0x00, // 2.3 speed + (byte) 0x09, (byte) 0x27, // 2.4 heading + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 4. mSec + (byte) 0x00, // 5. securityResultCode + (byte) 0x06, (byte) 0x00, // 6.0 payloadLength + // 6.1 payload + (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 + }; + + String filename = RecordType.bsmTx.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + String asn1String = data.getMetadata().getAsn1(); + var expected = String.format("{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"bsmTx.gz\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); + assertEquals(expected, data.toJson()); + } + } + + @Test + void testPublishDistressNotificationLogFile() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 1.1 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 1.2 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 1.3 elevation + (byte) 0x04, (byte) 0x00, // 1.4 speed + (byte) 0x09, (byte) 0x27, // 1.5 heading + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 3. mSec + (byte) 0x00, // 4. securityResultCode + (byte) 0x06, (byte) 0x00, // 5.1 payloadLength + // 5.2 payload + (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x40, (byte) 0x03, (byte) 0x80 + }; + + String filename = RecordType.dnMsg.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + var expected = String.format("{\"metadata\":{\"logFileName\":\"dnMsg.gz\",\"recordType\":\"dnMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"encodings\":[{\"elementName\":\"root\",\"elementType\":\"Ieee1609Dot2Data\",\"encodingRule\":\"COER\"},{\"elementName\":\"unsecuredData\",\"elementType\":\"MessageFrame\",\"encodingRule\":\"UPER\"}],\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"038100400380\"}}}", schemaVersion); + } + } + + @Test + void testPublishDriverAlertLogFile() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 1.0 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 1.1 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 1.2 elevation + (byte) 0x04, (byte) 0x00, // 1.3 speed + (byte) 0x09, (byte) 0x27, // 1.4 heading + + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 3. mSec + (byte) 0x11, (byte) 0x00, // 4.0 payloadLength + // 4.1 payload + 'T', 'e', 's', 't', ' ', 'D', 'r', 'i', 'v', 'e', 'r', ' ', 'A', 'l', 'e', 'r', 't' + }; + + String filename = RecordType.driverAlert.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + var expected = String.format("{\"metadata\":{\"logFileName\":\"driverAlert.gz\",\"recordType\":\"driverAlert\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeDriverAlertPayload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false},\"payload\":{\"alert\":\"Test Driver Alert\"}}", schemaVersion); + assertEquals(expected, data.toJson()); + } + } + + @Test + void testPublishRxMsgTIMLogFile() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x01, // 1. RxSource = SAT + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation + (byte) 0x04, (byte) 0x00, // 2.3 speed + (byte) 0x09, (byte) 0x27, // 2.4 heading + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 2. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 4. mSec + (byte) 0x00, // 5. securityResultCode + (byte) 0x06, (byte) 0x00, // 6.0 payloadLength + // 6.1 payload + (byte) 0x03, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 + }; + + String filename = RecordType.rxMsg.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + String asn1String = data.getMetadata().getAsn1(); + var expected = String.format("{\"metadata\":{\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"SAT\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"TMC_VIA_SAT\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); + assertEquals(expected, data.toJson()); + } + } + + @Test + void testPublishRxMsgBSMLogFile() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x02, // 1. RxSource = RV + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation + (byte) 0x04, (byte) 0x00, // 2.3 speed + (byte) 0x09, (byte) 0x27, // 2.4 heading + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 4. mSec + (byte) 0x00, // 5. securityResultCode + (byte) 0x06, (byte) 0x00, // 6.0 payloadLength + // 6.1 payload + (byte) 0x11, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80 + }; + + String filename = RecordType.rxMsg.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + String asn1String = data.getMetadata().getAsn1(); + var expected = String.format("{\"metadata\":{\"bsmSource\":\"RV\",\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"RV\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); + assertEquals(expected, data.toJson()); + } + } + + @Test + void testPublishNonLearLogFile() throws Exception { + + String filename = RecordType.rxMsg.name() + GZ; + + String jsonData = "{\"fakeJsonKey\":\"fakeJsonValue\""; + byte[] buf = jsonData.getBytes(); + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + /* + * This call to publish method does not actually try to parse the data. It + * short-circuits the parsing because + * currently we dont' support JSON input records. We may in the future. + */ + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.JSON_FILE); + + assertTrue(dataList.isEmpty()); + } + + @Test + void testPublishRxMsgBSMLogFileNewLine() throws Exception { + + byte[] buf = new byte[]{ + (byte) 0x02, // 1. RxSource = RV + (byte) 0x6f, (byte) 0x75, (byte) 0x4d, (byte) 0x19, // 2.0 latitude + (byte) 0xa4, (byte) 0xa1, (byte) 0x5c, (byte) 0xce, // 2.1 longitude + (byte) 0x67, (byte) 0x06, (byte) 0x00, (byte) 0x00, // 2.3 elevation + (byte) 0x04, (byte) 0x00, // 2.3 speed + (byte) 0x09, (byte) 0x27, // 2.4 heading + (byte) 0xa9, (byte) 0x2c, (byte) 0xe2, (byte) 0x5a, // 3. utcTimeInSec + (byte) 0x8f, (byte) 0x01, // 4. mSec + (byte) 0x00, // 5. securityResultCode + (byte) 0x06, (byte) 0x00, // 6.0 payloadLength + // 6.1 payload + (byte) 0x11, (byte) 0x81, (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x80, + (byte) 0x0a + }; + + String filename = RecordType.rxMsg.name() + GZ; + + BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(buf)); + + List dataList = testLogFileToAsn1CodecPublisher.publish(bis, filename, ImporterFileType.LOG_FILE); + + for (OdeData data : dataList) { + assertTrue(DateTimeUtils.difference(DateTimeUtils.isoDateTime(data.getMetadata().getRecordGeneratedAt()), + DateTimeUtils.nowZDT()) > 0); + data.getMetadata().setOdeReceivedAt("2019-03-05T20:31:17.579Z"); + data.getMetadata().getSerialId().setStreamId("c7bbb42e-1e39-442d-98ac-62740ca50f92"); + String asn1String = data.getMetadata().getAsn1(); + var expected = String.format("{\"metadata\":{\"bsmSource\":\"RV\",\"logFileName\":\"rxMsg.gz\",\"recordType\":\"rxMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"42.4506735\",\"longitude\":\"-83.2790108\",\"elevation\":\"163.9\",\"speed\":\"0.08\",\"heading\":\"124.9125\"},\"rxSource\":\"RV\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c7bbb42e-1e39-442d-98ac-62740ca50f92\",\"bundleSize\":1,\"bundleId\":1,\"recordId\":0,\"serialNumber\":1},\"odeReceivedAt\":\"2019-03-05T20:31:17.579Z\",\"schemaVersion\":%s,\"maxDurationTime\":0,\"recordGeneratedAt\":\"2018-04-26T19:46:49.399Z\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"asn1\":\"%s\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"%s\"}}}", schemaVersion, asn1String, asn1String); + assertEquals(expected, data.toJson()); + } + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java index 5488b8fb0..c11cb6cb1 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/ExporterTest.java @@ -46,9 +46,9 @@ void shouldRun(@Mocked OdeKafkaProperties odeKafkaProperties, }; try { - Exporter odeBsmExporter = new StompStringExporter(odeKafkaProperties, + Exporter odeBsmExporter = new StompStringExporter( testTopic, - mockSimpMessagingTemplate, "odeTopic"); + mockSimpMessagingTemplate, "odeTopic", odeKafkaProperties.getBrokers()); odeBsmExporter.setConsumer(mockStringConsumer); odeBsmExporter.run(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java index 1046052ba..dc6fbf7b4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java @@ -37,7 +37,9 @@ public class StompStringExporterTest { @Injectable SimpMessagingTemplate simpMessagingTemplate; @Injectable - String odeTopic; + String odeTopic = "testOdeTopic"; + @Injectable + String brokers = "localhost:9093"; @SuppressWarnings({ "rawtypes", "unchecked" }) @Test diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java index 35b3df2b4..c8165532a 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,84 +15,55 @@ ******************************************************************************/ package us.dot.its.jpo.ode.importer; -import java.io.IOException; -import java.nio.file.Path; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - import org.junit.jupiter.api.Test; - -import mockit.Capturing; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; +import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; - -public class ImporterDirectoryWatcherTest { - - @Tested - ImporterDirectoryWatcher testImporterDirectoryWatcher; - - @Injectable - OdeProperties injectableOdeProperties; - @Injectable - OdeKafkaProperties odeKafkaProperties; - @Injectable - Path inbox; - @Injectable - Path failureDir; - @Injectable - Path backupDir; - @Injectable - ImporterFileType injectableImporterFileType = ImporterFileType.LOG_FILE; - @Injectable - Integer timePeriod = 5; - - @Capturing - OdeFileUtils capturingOdeFileUtils; - @Capturing - ImporterProcessor capturingImporterProcessor; - @Capturing - Executors capturingExecutors; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; - @Mocked - ScheduledExecutorService mockScheduledExecutorService; - - // @BeforeEach - public void testConstructor() throws IOException { - new Expectations() { - { - OdeFileUtils.createDirectoryRecursively((Path) any); - times = 3; - - Executors.newScheduledThreadPool(1); - result = mockScheduledExecutorService; - } - }; - } - - @Test - public void testRun() throws InterruptedException, IOException { - new Expectations() { - { - OdeFileUtils.createDirectoryRecursively((Path) any); - times = 3; - - Executors.newScheduledThreadPool(1); - result = mockScheduledExecutorService; - - mockScheduledExecutorService.scheduleWithFixedDelay((Runnable) any, anyLong, anyLong, TimeUnit.SECONDS); - - mockScheduledExecutorService.awaitTermination(anyLong, TimeUnit.SECONDS); - } - }; - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, backupDir, failureDir, backupDir, injectableImporterFileType, timePeriod); +import java.nio.file.Files; +import java.nio.file.Path; - testImporterDirectoryWatcher.run(); - } +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, FileImporterProperties.class, JsonTopics.class, RawEncodedJsonTopics.class}) +class ImporterDirectoryWatcherTest { + + @Autowired + FileImporterProperties injectableFileImporterProperties; + @Autowired + OdeKafkaProperties odeKafkaProperties; + @Autowired + JsonTopics jsonTopics; + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + + @Test + void testConstructorCreatesThreeDirectories() { + + ImporterDirectoryWatcher testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableFileImporterProperties, + odeKafkaProperties, + jsonTopics, + ImporterDirectoryWatcher.ImporterFileType.LOG_FILE, + rawEncodedJsonTopics); + + assertNotNull(testImporterDirectoryWatcher); + Path inbox = Path.of(injectableFileImporterProperties.getUploadLocationRoot(), injectableFileImporterProperties.getObuLogUploadLocation()); + assertTrue(Files.exists(inbox)); + Path backups = Path.of(injectableFileImporterProperties.getUploadLocationRoot(), injectableFileImporterProperties.getBackupDir()); + assertTrue(Files.exists(backups)); + Path failures = Path.of(injectableFileImporterProperties.getUploadLocationRoot(), injectableFileImporterProperties.getFailedDir()); + assertTrue(Files.exists(failures)); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java deleted file mode 100644 index 69f984fb2..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTestOld.java +++ /dev/null @@ -1,136 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.importer; - -import static org.junit.Assert.fail; -import static org.junit.jupiter.api.Assertions.assertTimeout; - -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.WatchEvent; -import java.nio.file.WatchEvent.Kind; -import java.time.Duration; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import mockit.Capturing; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; - -@Disabled -public class ImporterDirectoryWatcherTestOld { - - ImporterDirectoryWatcher testImporterDirectoryWatcher; - - @Injectable - OdeProperties injectableOdeProperties; - @Injectable - OdeKafkaProperties odeKafkaProperties; - @Mocked - Path mockDir; - @Injectable - Path failureDir; - @Injectable - Path backupDir; - @Injectable - Integer timePeriod = 5; - - @Mocked - WatchKey mockWatchKey; - @Mocked - WatchService mockWatchService; - @Mocked - WatchEvent mockWatchEvent; - - @Capturing - OdeFileUtils capturingOdeFileUtils; - @Capturing - ImporterProcessor capturingImporterProcessor; - - @BeforeEach - public void createTestObject() { - try { - new Expectations() { - { - OdeFileUtils.createDirectoryRecursively((Path) any); - times = 3; - } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - testImporterDirectoryWatcher = new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); - testImporterDirectoryWatcher.setWatching(false); - } - - @Test - public void testConstructorOdeUtilsException() { - try { - new Expectations() { - { - OdeFileUtils.createDirectoryRecursively((Path) any); - result = new IOException("acceptionIsKindofAWord"); - } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - new ImporterDirectoryWatcher(injectableOdeProperties, odeKafkaProperties, mockDir, backupDir, failureDir, ImporterFileType.LOG_FILE, timePeriod); - } - - @Test - public void runShouldCatchException() { - assertTimeout(Duration.ofMillis(4000), () -> { - try { - new Expectations() { - { - mockDir.register((WatchService) any, (Kind) any); - result = null; - } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - testImporterDirectoryWatcher.run(); - }); - } - - @Test - @Timeout(4) - public void shouldRunNoProblems() { - try { - new Expectations() { - { - mockDir.register((WatchService) any, (Kind) any); - result = mockWatchKey; - } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - testImporterDirectoryWatcher.run(); - } - -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java new file mode 100644 index 000000000..de151d0b5 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java @@ -0,0 +1,40 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = Asn1CoderTopics.class) +class Asn1CoderTopicsTest { + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void getDecoderInput() { + assertEquals("topic.Asn1DecoderInput", asn1CoderTopics.getDecoderInput()); + } + + @Test + void getDecoderOutput() { + assertEquals("topic.Asn1DecoderOutput", asn1CoderTopics.getDecoderOutput()); + } + + @Test + void getEncoderInput() { + assertEquals("topic.Asn1EncoderInput", asn1CoderTopics.getEncoderInput()); + } + + @Test + void getEncoderOutput() { + assertEquals("topic.Asn1EncoderOutput", asn1CoderTopics.getEncoderOutput()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java new file mode 100644 index 000000000..b056fa233 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = FileTopics.class) +class FileTopicsTest { + + @Autowired + FileTopics fileTopics; + + @Test + void getFilteredOutput() { + assertEquals("/topic/filtered_messages", fileTopics.getFilteredOutput()); + } + + @Test + void getUnfilteredOutput() { + assertEquals("/topic/unfiltered_messages", fileTopics.getUnfilteredOutput()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java new file mode 100644 index 000000000..033edcc14 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java @@ -0,0 +1,110 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = JsonTopics.class) +class JsonTopicsTest { + + @Autowired + JsonTopics jsonTopics; + + @Test + void getBsm() { + assertEquals("topic.OdeBsmJson", jsonTopics.getBsm()); + } + + @Test + void getMap() { + assertEquals("topic.OdeMapJson", jsonTopics.getMap()); + } + + @Test + void getPsm() { + assertEquals("topic.OdePsmJson", jsonTopics.getPsm()); + } + + @Test + void getSpat() { + assertEquals("topic.OdeSpatJson", jsonTopics.getSpat()); + } + + @Test + void getSrm() { + assertEquals("topic.OdeSrmJson", jsonTopics.getSrm()); + } + + @Test + void getSsm() { + assertEquals("topic.OdeSsmJson", jsonTopics.getSsm()); + } + + @Test + void getTim() { + assertEquals("topic.OdeTimJson", jsonTopics.getTim()); + } + + @Test + void getDriverAlert() { + assertEquals("topic.OdeDriverAlertJson", jsonTopics.getDriverAlert()); + } + + @Test + void getTimBroadcast() { + assertEquals("topic.OdeTimBroadcastJson", jsonTopics.getTimBroadcast()); + } + + @Test + void getBsmFiltered() { + assertEquals("topic.FilteredOdeBsmJson", jsonTopics.getBsmFiltered()); + } + + @Test + void getSpatFiltered() { + assertEquals("topic.FilteredOdeSpatJson", jsonTopics.getSpatFiltered()); + } + + @Test + void getTimFiltered() { + assertEquals("topic.FilteredOdeTimJson", jsonTopics.getTimFiltered()); + } + + @Test + void getTimTmcFiltered() { + assertEquals("topic.OdeTimJsonTMCFiltered", jsonTopics.getTimTmcFiltered()); + } + + @Test + void getTimCertExpiration() { + assertEquals("topic.OdeTIMCertExpirationTimeJson", jsonTopics.getTimCertExpiration()); + } + + @Test + void getDnMessage() { + assertEquals("topic.OdeDNMsgJson", jsonTopics.getDnMessage()); + } + + @Test + void getRxTim() { + assertEquals("topic.OdeTimRxJson", jsonTopics.getRxTim()); + } + + @Test + void getRxSpat() { + assertEquals("topic.OdeSpatRxJson", jsonTopics.getRxSpat()); + } + + @Test + void getJ2735TimBroadcast() { + assertEquals("topic.J2735TimBroadcastJson", jsonTopics.getJ2735TimBroadcast()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java new file mode 100644 index 000000000..3a6d325a4 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java @@ -0,0 +1,80 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = PojoTopics.class) +class PojoTopicsTest { + + @Autowired + PojoTopics pojoTopics; + + @Test + void getBsm() { + assertEquals("topic.OdeBsmPojo", pojoTopics.getBsm()); + } + + @Test + void getSpat() { + assertEquals("topic.OdeSpatPojo", pojoTopics.getSpat()); + } + + @Test + void getSsm() { + assertEquals("topic.OdeSsmPojo", pojoTopics.getSsm()); + } + + @Test + void getTimBroadcast() { + assertEquals("topic.OdeTimBroadcastPojo", pojoTopics.getTimBroadcast()); + } + + @Test + void getBsmDuringEvent() { + assertEquals("topic.OdeBsmDuringEventPojo", pojoTopics.getBsmDuringEvent()); + } + + @Test + void getRxBsm() { + assertEquals("topic.OdeBsmRxPojo", pojoTopics.getRxBsm()); + } + + @Test + void getRxSpat() { + assertEquals("topic.OdeSpatRxPojo", pojoTopics.getRxSpat()); + } + + @Test + void getTxBsm() { + assertEquals("topic.OdeBsmTxPojo", pojoTopics.getTxBsm()); + } + + @Test + void getTxMap() { + assertEquals("topic.OdeMapTxPojo", pojoTopics.getTxMap()); + } + + @Test + void getTxPsm() { + assertEquals("topic.OdePsmTxPojo", pojoTopics.getTxPsm()); + } + + @Test + void getTxSpat() { + assertEquals("topic.OdeSpatTxPojo", pojoTopics.getTxSpat()); + } + + @Test + void getTxSrm() { + assertEquals("topic.OdeSrmTxPojo", pojoTopics.getTxSrm()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java new file mode 100644 index 000000000..afd023c6f --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java @@ -0,0 +1,55 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = RawEncodedJsonTopics.class) +class RawEncodedJsonTopicsTest { + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Test + void getBsm() { + assertEquals("topic.OdeRawEncodedBSMJson", rawEncodedJsonTopics.getBsm()); + } + + @Test + void getMap() { + assertEquals("topic.OdeRawEncodedMAPJson", rawEncodedJsonTopics.getMap()); + } + + @Test + void getPsm() { + assertEquals("topic.OdeRawEncodedPSMJson", rawEncodedJsonTopics.getPsm()); + } + + @Test + void getSpat() { + assertEquals("topic.OdeRawEncodedSPATJson", rawEncodedJsonTopics.getSpat()); + } + + @Test + void getSrm() { + assertEquals("topic.OdeRawEncodedSRMJson", rawEncodedJsonTopics.getSrm()); + } + + @Test + void getSsm() { + assertEquals("topic.OdeRawEncodedSSMJson", rawEncodedJsonTopics.getSsm()); + } + + @Test + void getTim() { + assertEquals("topic.OdeRawEncodedTIMJson", rawEncodedJsonTopics.getTim()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java new file mode 100644 index 000000000..df6cb08fa --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java @@ -0,0 +1,25 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = SDXDepositorTopics.class) +class SDXDepositorTopicsTest { + + @Autowired + SDXDepositorTopics sdxDepositorTopics; + + @Test + void getInput() { + assertEquals("topic.SDWDepositorInput", sdxDepositorTopics.getInput()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index b8d8415c0..8decd40ff 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -27,6 +27,7 @@ import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeTravelerInputData; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; import us.dot.its.jpo.ode.snmp.SnmpSession; @@ -43,6 +44,9 @@ public class Asn1CommandManagerTest { @Injectable OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable + SDXDepositorTopics injectableSDXDepositorTopics; + @Capturing MessageProducer capturingMessageProducer; @Capturing diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java index c4db680b7..b25c78dc4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,44 +15,42 @@ ******************************************************************************/ package us.dot.its.jpo.ode.services.asn1; -import static org.junit.Assert.assertNotNull; - -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - import mockit.Expectations; import mockit.Injectable; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.*; import us.dot.its.jpo.ode.wrapper.MessageConsumer; -public class AsnCodecRouterServiceControllerTest { - -// @Capturing -// MessageConsumer capturingMessageConsumer; -// -// @Capturing -// Asn1DecodedDataRouter capturingAsn1DecodedDataRouter; -// -// @Capturing -// Asn1EncodedDataRouter capturingAsn1EncodedDataRouter; - - @Injectable - OdeProperties injectableOdeProperties; - @Injectable - OdeKafkaProperties odeKafkaProperties; - - @Test @Disabled - public void shouldStartTwoConsumers() { - - new Expectations() { - { - MessageConsumer.defaultStringMessageConsumer(anyString, anyString, (Asn1DecodedDataRouter) any); - times = 2; - } - }; - - assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties, odeKafkaProperties)); - } +import static org.junit.Assert.assertNotNull; +class AsnCodecRouterServiceControllerTest { + + @Injectable + OdeProperties injectableOdeProperties; + @Injectable + OdeKafkaProperties odeKafkaProperties; + @Injectable + JsonTopics jsonTopics; + @Injectable + PojoTopics pojoTopics; + @Injectable + Asn1CoderTopics asn1CoderTopics; + @Injectable + SDXDepositorTopics sdxDepositorTopics; + + @Test + @Disabled + void shouldStartTwoConsumers() { + + new Expectations() { + { + MessageConsumer.defaultStringMessageConsumer(anyString, anyString, (Asn1DecodedDataRouter) any); + times = 2; + } + }; + + assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties, odeKafkaProperties, jsonTopics, pojoTopics, asn1CoderTopics, sdxDepositorTopics)); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index f29edca97..a77203887 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -8,7 +8,9 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -19,33 +21,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeBSMJSONTest { private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals(properties.getKafkaTopicOdeRawEncodedBSMJson(), "topic.OdeRawEncodedBSMJson"); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - - Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(properties, odeKafkaProperties); + Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); // Validate the metadata OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); assertEquals(OdeBsmMetadata.BsmSource.EV, jsonMetadataObj.getBsmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java index dda58a276..950fdf362 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java @@ -8,7 +8,8 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -19,32 +20,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeMAPJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals("topic.OdeRawEncodedMAPJson", properties.getKafkaTopicOdeRawEncodedMAPJson()); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(properties, odeKafkaProperties); + Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); // Validate the metadata OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); assertEquals(OdeMapMetadata.MapSource.RSU, jsonMetadataObj.getMapSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index 6dcf1ecd0..026d114f6 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -8,49 +8,45 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) -public class Asn1DecodePSMJSONTest { +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +class Asn1DecodePSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - public void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals(properties.getKafkaTopicOdeRawEncodedPSMJson(), "topic.OdeRawEncodedPSMJson"); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; + @Test - public void testProcess() throws XmlUtilsException, JSONException { - OdeProperties properties = new OdeProperties(); - Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(properties, odeKafkaProperties); + void testProcess() throws JSONException { + Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); // Validate the metadata OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); - assertEquals(jsonMetadataObj.getPsmSource(), OdePsmMetadata.PsmSource.RSU); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementName(), "unsecuredData"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getElementType(), "MessageFrame"); - assertEquals(jsonMetadataObj.getEncodings().get(0).getEncodingRule(), EncodingRule.UPER); + assertEquals(OdePsmMetadata.PsmSource.RSU, jsonMetadataObj.getPsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals(jsonPayloadObj.getDataType(), "us.dot.its.jpo.ode.model.OdeHexByteArray"); - assertEquals(jsonPayloadObj.getData().toString(), expectedPayload); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index a9ae8c31c..23d1bc28c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -8,7 +8,7 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -19,33 +19,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSPATJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - - assertEquals("topic.OdeRawEncodedSPATJson", properties.getKafkaTopicOdeRawEncodedSPATJson()); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(properties, odeKafkaProperties); + Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); // Validate the metadata OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); assertEquals(OdeSpatMetadata.SpatSource.RSU, jsonMetadataObj.getSpatSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index ac29a8145..b9e704123 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -19,33 +20,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSRMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals("topic.OdeRawEncodedSRMJson", properties.getKafkaTopicOdeRawEncodedSRMJson()); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - - Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(properties, odeKafkaProperties); + Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); // Validate the metadata OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); assertEquals(OdeSrmMetadata.SrmSource.RSU, jsonMetadataObj.getSrmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 26a702d07..14a330d00 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -19,32 +20,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals("topic.OdeRawEncodedSSMJson", properties.getKafkaTopicOdeRawEncodedSSMJson()); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(properties, odeKafkaProperties); + Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); // Validate the metadata OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); assertEquals(OdeSsmMetadata.SsmSource.RSU, jsonMetadataObj.getSsmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index d4f6786f3..5cf14ae26 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -9,6 +9,7 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -20,32 +21,28 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeTIMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @Autowired OdeKafkaProperties odeKafkaProperties; - @Test - void testConstructor() { - OdeProperties properties = new OdeProperties(); - assertEquals("topic.OdeRawEncodedTIMJson", properties.getKafkaTopicOdeRawEncodedTIMJson()); - } + @Autowired + Asn1CoderTopics asn1CoderTopics; @Test void testProcess() throws JSONException { - OdeProperties properties = new OdeProperties(); - Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(properties, odeKafkaProperties); + Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); // Validate the metadata OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); assertEquals(OdeMsgMetadata.GeneratedBy.RSU, jsonMetadataObj.getRecordGeneratedBy()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().get(0).getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().get(0).getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().get(0).getEncodingRule()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); // Validate the payload String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java index bed8866d9..ba1b2ecf4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java @@ -8,23 +8,29 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import static org.junit.Assert.assertNotNull; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = OdeKafkaProperties.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, RawEncodedJsonTopics.class, Asn1CoderTopics.class}) class AsnCodecMessageServiceControllerTest { @Autowired OdeKafkaProperties odeKafkaProps; + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + @Test void shouldStartTwoConsumers() { - OdeProperties odeProps = new OdeProperties(); - - AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeProps, odeKafkaProps); + AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeKafkaProps, rawEncodedJsonTopics, asn1CoderTopics); assertNotNull(asnCodecMessageServiceController); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java index bee54d235..7090d2ef6 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java @@ -19,17 +19,21 @@ import mockit.Expectations; import mockit.Injectable; +import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; public class ToJsonServiceControllerTest { - @Injectable - OdeProperties odeProperties; @Injectable OdeKafkaProperties mockOdeKafkaProperties; + @Injectable + JsonTopics jsonTopics; + @Injectable + PojoTopics pojoTopics; // @Capturing // ToJsonConverter capturingToJsonConverter; @@ -40,7 +44,7 @@ public class ToJsonServiceControllerTest { public void test() { new Expectations() { { - new ToJsonConverter<>((OdeProperties) any, (OdeKafkaProperties) any, anyBoolean, anyString); + new ToJsonConverter<>((OdeKafkaProperties) any, anyBoolean, anyString); times = 1; new MessageConsumer<>(anyString, anyString, (MessageProcessor) any, anyString); @@ -48,7 +52,7 @@ public void test() { } }; - new ToJsonServiceController(odeProperties, mockOdeKafkaProperties); + new ToJsonServiceController(mockOdeKafkaProperties, jsonTopics, pojoTopics); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java index a703eceed..64293e8a7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java @@ -31,9 +31,15 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.core.io.UrlResource; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.util.FileSystemUtils; import org.springframework.web.multipart.MultipartFile; @@ -41,33 +47,16 @@ import mockit.Mocked; import mockit.Verifications; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.eventlog.EventLogger; +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = FileImporterProperties.class) public class FileSystemStorageServiceTest { - @Mocked - OdeProperties mockOdeProperties; - - @BeforeEach - public void setupOdePropertiesExpectations() { - new Expectations() { - { - mockOdeProperties.getUploadLocationRoot(); - result = anyString; - mockOdeProperties.getUploadLocationObuLog(); - result = anyString; - } - }; - } - - @Test - public void shouldConstruct(@Mocked final Logger mockLogger, @Mocked LoggerFactory unused) { - - FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(mockOdeProperties); - - assertNotNull(testFileSystemStorageService.getRootLocation()); - - } + @Autowired + private FileImporterProperties fileImporterProperties; @Test @Disabled public void storeShouldThrowExceptionUnknownType(@Mocked MultipartFile mockMultipartFile) { @@ -75,7 +64,7 @@ public void storeShouldThrowExceptionUnknownType(@Mocked MultipartFile mockMulti String unknownType = "test123"; try { - new FileSystemStorageService(mockOdeProperties).store(mockMultipartFile, unknownType); + new FileSystemStorageService(fileImporterProperties).store(mockMultipartFile, unknownType); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -105,7 +94,7 @@ public void storeShouldTryToResolveBsmFilename(@Mocked MultipartFile mockMultipa }; try { - new FileSystemStorageService(mockOdeProperties).store(mockMultipartFile, testType); + new FileSystemStorageService(fileImporterProperties).store(mockMultipartFile, testType); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -134,7 +123,7 @@ public void storeShouldThrowAnErrorEmptyFile(@Mocked MultipartFile mockMultipart }; try { - new FileSystemStorageService(mockOdeProperties).store(mockMultipartFile, testType); + new FileSystemStorageService(fileImporterProperties).store(mockMultipartFile, testType); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -174,7 +163,7 @@ public void storeShouldRethrowDeleteException(@Mocked MultipartFile mockMultipar } try { - new FileSystemStorageService(mockOdeProperties).store(mockMultipartFile, testType); + new FileSystemStorageService(fileImporterProperties).store(mockMultipartFile, testType); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -218,7 +207,7 @@ public void storeShouldRethrowCopyException(@Mocked MultipartFile mockMultipartF } try { - new FileSystemStorageService(mockOdeProperties).store(mockMultipartFile, testType); + new FileSystemStorageService(fileImporterProperties).store(mockMultipartFile, testType); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -248,7 +237,7 @@ public void loadAllShouldRethrowException(/**@Mocked Files unused**/) { } try { - new FileSystemStorageService(mockOdeProperties).loadAll(); + new FileSystemStorageService(fileImporterProperties).loadAll(); fail("Expected StorageException"); } catch (Exception e) { assertEquals("Incorrect exception thrown", StorageException.class, e.getClass()); @@ -288,8 +277,7 @@ public void loadAsResourceShouldThrowExceptionWhenFileNotExists( } try { - FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(mockOdeProperties); - testFileSystemStorageService.setRootLocation(mockRootPath); + FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(fileImporterProperties); testFileSystemStorageService.loadAsResource("testFile"); fail("Expected StorageFileNotFoundException"); } catch (Exception e) { @@ -325,8 +313,7 @@ public void loadAsResourceShouldThrowExceptionWhenFileNotReadable(@Mocked Path m } try { - FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(mockOdeProperties); - testFileSystemStorageService.setRootLocation(mockRootPath); + FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(fileImporterProperties); testFileSystemStorageService.loadAsResource("testFile"); fail("Expected StorageFileNotFoundException"); } catch (Exception e) { @@ -356,8 +343,8 @@ public void loadAsResourceShouldRethrowMalformedURLException(@Mocked Path mockRo } try { - FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(mockOdeProperties); - testFileSystemStorageService.setRootLocation(mockRootPath); + FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(fileImporterProperties); + testFileSystemStorageService.loadAsResource("testFile"); fail("Expected StorageFileNotFoundException"); } catch (Exception e) { @@ -392,8 +379,8 @@ public void loadAsResourceShouldReturnResource(@Mocked Path mockRootPath, @Mocke } try { - FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(mockOdeProperties); - testFileSystemStorageService.setRootLocation(mockRootPath); + FileSystemStorageService testFileSystemStorageService = new FileSystemStorageService(fileImporterProperties); + assertEquals(UrlResource.class, testFileSystemStorageService.loadAsResource("testFile").getClass()); } catch (Exception e) { fail("Unexpected exception: " + e); @@ -403,7 +390,7 @@ public void loadAsResourceShouldReturnResource(@Mocked Path mockRootPath, @Mocke @Test @Disabled public void initShouldCreateDirectories(@Mocked final Files unused) { - new FileSystemStorageService(mockOdeProperties).init(); + new FileSystemStorageService(fileImporterProperties).init(); try { new Verifications() { @@ -432,7 +419,7 @@ public void initShouldRethrowAndLogException(@Mocked final Files unused) { } try { - new FileSystemStorageService(mockOdeProperties).init(); + new FileSystemStorageService(fileImporterProperties).init(); } catch (Exception e) { assertEquals("Incorrect exception thrown.", StorageException.class, e.getClass()); assertTrue("Incorrect exception message", @@ -449,7 +436,7 @@ public void initShouldRethrowAndLogException(@Mocked final Files unused) { @Test @Disabled public void deleteAllShouldDeleteRecursivelyAndLog(@Mocked final FileSystemUtils unused) { - new FileSystemStorageService(mockOdeProperties).deleteAll(); + new FileSystemStorageService(fileImporterProperties).deleteAll(); new Verifications() { { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index f0e21e19a..481d6515a 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -27,8 +27,11 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; @@ -50,6 +53,18 @@ public class TimDepositControllerTest { @Injectable OdeKafkaProperties injectableOdeKafkaProperties; + @Injectable + Asn1CoderTopics injectableAsn1CoderTopics; + + @Injectable + PojoTopics injectablePojoTopics; + + @Injectable + JsonTopics injectableJsonTopics; + + @Injectable + TimIngestTrackerProperties injectableTimIngestTrackerProperties; + @Capturing MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidatorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidatorTest.java new file mode 100644 index 000000000..4cd4fc812 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestPropertiesValidatorTest.java @@ -0,0 +1,42 @@ +package us.dot.its.jpo.ode.traveler; + +import org.junit.jupiter.api.Test; +import org.springframework.validation.BeanPropertyBindingResult; + +import static org.junit.jupiter.api.Assertions.*; + +class TimIngestPropertiesValidatorTest { + + @Test + void supports() { + TimIngestPropertiesValidator validator = new TimIngestPropertiesValidator(); + assertTrue(validator.supports(TimIngestTrackerProperties.class)); + assertFalse(validator.supports(Object.class)); + } + + @Test + void validate() { + TimIngestTrackerProperties properties = new TimIngestTrackerProperties(); + properties.setTrackingEnabled(true); + properties.setInterval(1); + + TimIngestPropertiesValidator validator = new TimIngestPropertiesValidator(); + BeanPropertyBindingResult errors = new BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertFalse(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidMonitoringInterval() { + TimIngestTrackerProperties properties = new TimIngestTrackerProperties(); + properties.setTrackingEnabled(true); + properties.setInterval(0); + + TimIngestPropertiesValidator validator = new TimIngestPropertiesValidator(); + BeanPropertyBindingResult errors = new BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java new file mode 100644 index 000000000..2d6ecf6eb --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.traveler; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = TimIngestTrackerProperties.class) +class TimIngestTrackerPropertiesTest { + + @Autowired + TimIngestTrackerProperties timIngestTrackerProperties; + + @Test + void isTrackingEnabled() { + assertTrue(timIngestTrackerProperties.isTrackingEnabled()); + } + + @Test + void getMonitoringInterval() { + assertEquals(1, timIngestTrackerProperties.getInterval()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java index f5a417461..fc216b254 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,13 +15,7 @@ ******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.util.Vector; - +import mockit.*; import org.junit.jupiter.api.Test; import org.snmp4j.PDU; import org.snmp4j.Snmp; @@ -30,461 +24,460 @@ import org.snmp4j.smi.VariableBinding; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; - -import mockit.Capturing; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; import us.dot.its.jpo.ode.snmp.SnmpSession; -public class TimQueryControllerTest { - - @Tested - TimQueryController testTimQueryController; - - @Injectable - OdeProperties mockOdeProperties; - - @Capturing - SnmpSession capturingSnmpSession; - - @Mocked - Snmp mockSnmp; - @Mocked - ResponseEvent mockResponseEvent; - @Mocked - PDU mockPDU; - - private String defaultRSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\"}"; - private String fourDot1RSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"FOURDOT1\"}"; - private String ntcip1218RSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"NTCIP1218\"}"; - - @Test - public void nullRequestShouldReturnError() { - ResponseEntity result = testTimQueryController.bulkQuery(null); - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - assertEquals("{\"error\":\"Empty request.\"}", result.getBody()); - } - - @Test - public void emptyRequestShouldReturnError() { - ResponseEntity result = testTimQueryController.bulkQuery(""); - assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); - assertEquals("{\"error\":\"Empty request.\"}", result.getBody()); - } - - @Test - public void snmpSessionExceptionShouldReturnError() { - try { - new Expectations() { +import java.io.IOException; +import java.util.Vector; + +import static org.junit.jupiter.api.Assertions.*; + +class TimQueryControllerTest { + + @Tested + TimQueryController testTimQueryController; + + @Injectable + OdeProperties mockOdeProperties; + + @Capturing + SnmpSession capturingSnmpSession; + + @Mocked + Snmp mockSnmp; + @Mocked + ResponseEvent mockResponseEvent; + @Mocked + PDU mockPDU; + + private final String defaultRSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\"}"; + private final String fourDot1RSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"FOURDOT1\"}"; + private final String ntcip1218RSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"NTCIP1218\"}"; + + @Test + void nullRequestShouldReturnError() { + ResponseEntity result = testTimQueryController.bulkQuery(null); + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + assertEquals("{\"error\":\"Empty request.\"}", result.getBody()); + } + + @Test + void emptyRequestShouldReturnError() { + ResponseEntity result = testTimQueryController.bulkQuery(""); + assertEquals(HttpStatus.BAD_REQUEST, result.getStatusCode()); + assertEquals("{\"error\":\"Empty request.\"}", result.getBody()); + } + + @Test + void snmpSessionExceptionShouldReturnError() { + try { + new Expectations() { + { + new SnmpSession((RSU) any); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void snmpSessionExceptionShouldReturnError_fourDot1RSU() { + try { + new Expectations() { + { + new SnmpSession((RSU) any); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void snmpSessionExceptionShouldReturnError_ntcip1218RSU() { + try { + new Expectations() { + { + new SnmpSession((RSU) any); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void snmpSessionListenExceptionShouldReturnError() { + try { + new Expectations() { + { + capturingSnmpSession.startListen(); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void snmpSessionListenExceptionShouldReturnError_fourDot1RSU() { + try { + new Expectations() { + { + capturingSnmpSession.startListen(); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void snmpSessionListenExceptionShouldReturnError_ntcip1218RSU() { + try { + new Expectations() { + { + capturingSnmpSession.startListen(); + result = new IOException("testException123"); + } + }; + } catch (IOException e) { + fail("Unexpected exception in expectations block: " + e); + } + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); + } + + @Test + void testNullResponseReturnsTimeout() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = null; + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testNullResponseReturnsTimeout_fourDot1RSU() throws IOException { + new Expectations() { { - new SnmpSession((RSU) any); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = null; } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void snmpSessionExceptionShouldReturnError_fourDot1RSU() { - try { - new Expectations() { + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testNullResponseReturnsTimeout_ntcip1218RSU() throws IOException { + new Expectations() { { - new SnmpSession((RSU) any); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = null; } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void snmpSessionExceptionShouldReturnError_ntcip1218RSU() { - try { - new Expectations() { + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testNullResponseResponseReturnsTimeout() throws IOException { + new Expectations() { { - new SnmpSession((RSU) any); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = null; } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void snmpSessionListenExceptionShouldReturnError() { - try { - new Expectations() { + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testNullResponseResponseReturnsTimeout_fourDot1RSU() throws IOException { + new Expectations() { { - capturingSnmpSession.startListen(); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = null; } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void snmpSessionListenExceptionShouldReturnError_fourDot1RSU() { - try { - new Expectations() { + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testNullResponseResponseReturnsTimeout_ntcip1218RSU() throws IOException { + new Expectations() { { - capturingSnmpSession.startListen(); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = null; } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void snmpSessionListenExceptionShouldReturnError_ntcip1218RSU() { - try { - new Expectations() { + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); + } + + @Test + void testSuccessfulQuery() throws IOException { + new Expectations() { { - capturingSnmpSession.startListen(); - result = new IOException("testException123"); + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + mockPDU.getVariableBindings(); + result = new Vector(); } - }; - } catch (IOException e) { - fail("Unexpected exception in expectations block: " + e); - } - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Failed to create SNMP session.")); - } - - @Test - public void testNullResponseReturnsTimeout() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testNullResponseReturnsTimeout_fourDot1RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testNullResponseReturnsTimeout_ntcip1218RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testNullResponseResponseReturnsTimeout() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testNullResponseResponseReturnsTimeout_fourDot1RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testNullResponseResponseReturnsTimeout_ntcip1218RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = null; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Timeout, no response from RSU.")); - } - - @Test - public void testSuccessfulQuery() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - mockPDU.getVariableBindings(); - result = new Vector(); - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testSuccessfulQuery_fourDot1RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - mockPDU.getVariableBindings(); - result = new Vector(); - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testSuccessfulQuery_ntcip1218RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - mockPDU.getVariableBindings(); - result = new Vector(); - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testSuccessfulPopulatedQuery() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - Vector fakeVector = new Vector(); - fakeVector.add(new VariableBinding()); - - mockPDU.getVariableBindings(); - result = fakeVector; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testSuccessfulPopulatedQuery_fourDot1RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - Vector fakeVector = new Vector(); - fakeVector.add(new VariableBinding()); - - mockPDU.getVariableBindings(); - result = fakeVector; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testSuccessfulPopulatedQuery_ntcip1218RSU() throws IOException { - new Expectations() { - { - mockOdeProperties.getRsuSrmSlots(); - result = 1; - - capturingSnmpSession.getSnmp(); - result = mockSnmp; - - mockSnmp.send((PDU) any, (UserTarget) any); - result = mockResponseEvent; - - mockResponseEvent.getResponse(); - result = mockPDU; - - Vector fakeVector = new Vector(); - fakeVector.add(new VariableBinding()); - - mockPDU.getVariableBindings(); - result = fakeVector; - } - }; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); - assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("indicies_set")); - } - - @Test - public void testPopulatedQuery_unrecognizedProtocol() throws IOException { - String unrecognizedProtocolRSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"banana\"}"; - - ResponseEntity actualResponse = testTimQueryController.bulkQuery(unrecognizedProtocolRSU); - assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); - assertTrue(actualResponse.getBody().contains("Unrecognized protocol")); - } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testSuccessfulQuery_fourDot1RSU() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + mockPDU.getVariableBindings(); + result = new Vector(); + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testSuccessfulQuery_ntcip1218RSU() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + mockPDU.getVariableBindings(); + result = new Vector(); + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testSuccessfulPopulatedQuery() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + Vector fakeVector = new Vector(); + fakeVector.add(new VariableBinding()); + + mockPDU.getVariableBindings(); + result = fakeVector; + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(defaultRSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testSuccessfulPopulatedQuery_fourDot1RSU() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + Vector fakeVector = new Vector(); + fakeVector.add(new VariableBinding()); + + mockPDU.getVariableBindings(); + result = fakeVector; + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(fourDot1RSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testSuccessfulPopulatedQuery_ntcip1218RSU() throws IOException { + new Expectations() { + { + mockOdeProperties.rsuProperties().getSrmSlots(); + result = 1; + + capturingSnmpSession.getSnmp(); + result = mockSnmp; + + mockSnmp.send((PDU) any, (UserTarget) any); + result = mockResponseEvent; + + mockResponseEvent.getResponse(); + result = mockPDU; + + Vector fakeVector = new Vector(); + fakeVector.add(new VariableBinding()); + + mockPDU.getVariableBindings(); + result = fakeVector; + } + }; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(ntcip1218RSU); + assertEquals(HttpStatus.OK, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("indicies_set")); + } + + @Test + void testPopulatedQuery_unrecognizedProtocol() throws IOException { + String unrecognizedProtocolRSU = "{\"rsuTarget\":\"10.10.10.10\",\"rsuUsername\":\"user\",\"rsuPassword\":\"pass\",\"rsuRetries\":\"3\",\"rsuTimeout\":\"5000\",\"snmpProtocol\":\"banana\"}"; + + ResponseEntity actualResponse = testTimQueryController.bulkQuery(unrecognizedProtocolRSU); + assertEquals(HttpStatus.BAD_REQUEST, actualResponse.getStatusCode()); + assertTrue(actualResponse.getBody().contains("Unrecognized protocol")); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 9a2446f81..5af7cf4d6 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -1,28 +1,10 @@ package us.dot.its.jpo.ode.traveler; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; - -import org.json.JSONObject; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; - -import mockit.Capturing; -import mockit.Expectations; -import mockit.Mock; -import mockit.MockUp; -import mockit.Mocked; +import mockit.*; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; @@ -42,26 +24,27 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -public class TimTransmogrifierTest { +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; + +import static org.junit.Assert.*; + +class TimTransmogrifierTest { @Mocked OdeProperties mockOdeProperties; private static String schemaVersion = "7"; - @BeforeAll - public static void setupClass() { - schemaVersion = Integer.toString(OdeProperties.OUTPUT_SCHEMA_VERSION); - } - @Test - public void testGetRsu() throws IOException { + void testGetRsu() { new Expectations() { { - mockOdeProperties.getRsuUsername(); + mockOdeProperties.rsuProperties().getUsername(); result = "v3user"; - mockOdeProperties.getRsuPassword(); + mockOdeProperties.rsuProperties().getPassword(); result = "password"; } }; @@ -85,7 +68,7 @@ public void testGetRsu() throws IOException { } @Test - public void testObfuscateRsuPassword() { + void testObfuscateRsuPassword() { String actual = TimTransmogrifier.obfuscateRsuPassword( "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); assertEquals( @@ -93,7 +76,7 @@ public void testObfuscateRsuPassword() { actual); } - public void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) + void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) throws JsonUtilsException, XmlUtilsException { JsonNode obj = JsonUtils.toObjectNode(array); JsonNode oldObj = obj.get(arrayKey); @@ -105,7 +88,7 @@ public void assertConvertArray(String array, String arrayKey, String elementKey, } @Test - public void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { + void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; String singleXmlExpected = "127.0.0.3v3userpassword1100010"; assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); @@ -116,13 +99,13 @@ public void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException } @Test - public void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { + void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); assertNull(actualASD); } @Test - public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws TimTransmogrifierException { + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws TimTransmogrifierException { ServiceRequest inputServiceRequest = new ServiceRequest(); inputServiceRequest.setSdw(new SDW()); @@ -137,7 +120,7 @@ public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws Ti } @Test - public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws TimTransmogrifierException { + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws TimTransmogrifierException { ServiceRequest inputServiceRequest = new ServiceRequest(); inputServiceRequest.setSdw(new SDW()); @@ -151,7 +134,7 @@ public void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws Tim } @Test - public void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) + void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) throws TimTransmogrifierException { SNMP inputSNMP = new SNMP(); @@ -170,7 +153,7 @@ public void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingG } @Test - public void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) + void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) throws TimTransmogrifierException { SDW inputSDW = new SDW(); @@ -188,7 +171,7 @@ public void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGe } @Test - public void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, + void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, @Capturing GeoRegionBuilder capturingGeoRegionBuilder) throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { @@ -201,7 +184,7 @@ public void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, new MockUp() { @Mock - public DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { + DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { return new DdsGeoRegion(); } }; @@ -236,7 +219,7 @@ public DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { } @Test - public void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateTimeUtils, + void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateTimeUtils, @Capturing GeoRegionBuilder capturingGeoRegionBuilder) throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { @@ -276,7 +259,7 @@ public void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateT } @Test - public void testCreateOdeTimData() throws JsonUtilsException { + void testCreateOdeTimData() throws JsonUtilsException { JSONObject testObject = JsonUtils .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); @@ -288,7 +271,7 @@ public void testCreateOdeTimData() throws JsonUtilsException { } @Test - public void testConstructorIsPrivate() + void testConstructorIsPrivate() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java index 1d56aca12..83d5e2e37 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -19,15 +19,18 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.multipart.MultipartFile; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; +import us.dot.its.jpo.ode.kafka.FileTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; import us.dot.its.jpo.ode.storage.StorageService; @@ -36,83 +39,91 @@ import static org.junit.Assert.assertEquals; -public class FileUploadControllerTest { - - FileUploadController testFileUploadController; - - @Mocked - StorageService mockStorageService; - - @Injectable - OdeProperties injectableOdeProperties; - - @Injectable - OdeKafkaProperties injectableOdeKafkaProperties; - - @Injectable - SimpMessagingTemplate injectableSimpMessagingTemplate; - - @Capturing - Executors capturingExecutors; - @Capturing - ImporterDirectoryWatcher capturingImporterDirectoryWatcher; - @Mocked - ExecutorService mockExecutorService; - - @Mocked - OdeProperties mockOdeProperties; - - @Mocked - MultipartFile mockMultipartFile; - - @BeforeEach - public void constructorShouldLaunchSevenThreads() { - new Expectations() { - { - mockOdeProperties.getUploadLocationRoot(); - result = "testRootDir"; - mockOdeProperties.getUploadLocationObuLog(); - result = "testLogFileDir"; - - Executors.newCachedThreadPool(); - result = mockExecutorService; - - mockExecutorService.submit((Runnable) any); - times = 11; - } - }; - testFileUploadController = new FileUploadController(mockStorageService, mockOdeProperties, injectableOdeKafkaProperties, - injectableSimpMessagingTemplate); - } - - @Test - public void handleFileUploadReturnsErrorOnStorageException() { - new Expectations() { - { - mockStorageService.store((MultipartFile) any, anyString); - result = new StorageFileNotFoundException("testException123"); - } - }; - - assertEquals(HttpStatus.BAD_REQUEST, - testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode()); - } - - @Test - public void successfulUploadReturnsHttpOk() { - new Expectations() { - { - mockStorageService.store((MultipartFile) any, anyString); - times = 1; - } - }; - - assertEquals(HttpStatus.OK, testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode()); - } - - @Test - public void testStorageFileNotFoundException() { - assertEquals(HttpStatus.NOT_FOUND, testFileUploadController - .handleStorageFileNotFound(new StorageFileNotFoundException("testException123")).getStatusCode()); - } +class FileUploadControllerTest { + + FileUploadController testFileUploadController; + + @Mocked + StorageService mockStorageService; + + @Injectable + OdeProperties injectableOdeProperties; + + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + + @Injectable + SimpMessagingTemplate injectableSimpMessagingTemplate; + + @Injectable + FileImporterProperties fileImporterProps; + + @Injectable + FileTopics fileTopics; + + @Injectable + JsonTopics jsonTopics; + + @Injectable + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Capturing + Executors capturingExecutors; + @Capturing + ImporterDirectoryWatcher capturingImporterDirectoryWatcher; + @Mocked + ExecutorService mockExecutorService; + + @Mocked + OdeProperties mockOdeProperties; + + @Mocked + MultipartFile mockMultipartFile; + + @BeforeEach + public void constructorShouldLaunchSevenThreads() { + new Expectations() { + { + Executors.newCachedThreadPool(); + result = mockExecutorService; + + mockExecutorService.submit((Runnable) any); + times = 11; + } + }; + + testFileUploadController = new FileUploadController(mockStorageService, + injectableSimpMessagingTemplate, fileImporterProps, fileTopics, jsonTopics, rawEncodedJsonTopics, injectableOdeKafkaProperties); + } + + @Test + void handleFileUploadReturnsErrorOnStorageException() { + new Expectations() { + { + mockStorageService.store((MultipartFile) any, anyString); + result = new StorageFileNotFoundException("testException123"); + } + }; + + assertEquals(HttpStatus.BAD_REQUEST, + testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode()); + } + + @Test + void successfulUploadReturnsHttpOk() { + new Expectations() { + { + mockStorageService.store((MultipartFile) any, anyString); + times = 1; + } + }; + + assertEquals(HttpStatus.OK, testFileUploadController.handleFileUpload(mockMultipartFile, "type").getStatusCode()); + } + + @Test + void testStorageFileNotFoundException() { + assertEquals(HttpStatus.NOT_FOUND, testFileUploadController + .handleStorageFileNotFound(new StorageFileNotFoundException("testException123")).getStatusCode()); + } } diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml index cd3de12c1..8c14ff1e1 100644 --- a/jpo-ode-svcs/src/test/resources/application.yaml +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -1,10 +1,110 @@ +spring: + http: + multipart: + max-file-size: 1MB + max-request-size: 1MB ode: - host-ip: test-host + host-ip: "test-host" + verbose-json: false + plugins-locations: "plugins" + output-schema-version: 7 + security-svcs-port: 8090 + security-svcs-signature-endpoint: "sign" + rsu: + srm-slots: 100 + username: "test-username" + password: "test-password" kafka: - brokers: localhost:9092 + brokers: "localhost:9092" producer-type: sync disabled-topics: - "topic.OdeBsmRxPojo" - "topic.OdeBsmTxPojo" - "topic.OdeBsmDuringEventPojo" - - "topic.OdeTimBroadcastPojo" \ No newline at end of file + - "topic.OdeTimBroadcastPojo" + topics: + asn1: + decoder-input: "topic.Asn1DecoderInput" + decoder-output: "topic.Asn1DecoderOutput" + encoder-input: "topic.Asn1EncoderInput" + encoder-output: "topic.Asn1EncoderOutput" + json: + bsm: "topic.OdeBsmJson" + map: "topic.OdeMapJson" + psm: "topic.OdePsmJson" + spat: "topic.OdeSpatJson" + srm: "topic.OdeSrmJson" + ssm: "topic.OdeSsmJson" + tim: "topic.OdeTimJson" + driver-alert: "topic.OdeDriverAlertJson" + tim-broadcast: "topic.OdeTimBroadcastJson" + bsm-filtered: "topic.FilteredOdeBsmJson" + spat-filtered: "topic.FilteredOdeSpatJson" + tim-filtered: "topic.FilteredOdeTimJson" + tim-tmc-filtered: "topic.OdeTimJsonTMCFiltered" + tim-cert-expiration: "topic.OdeTIMCertExpirationTimeJson" + dn-message: "topic.OdeDNMsgJson" + rx-tim: "topic.OdeTimRxJson" + rx-spat: "topic.OdeSpatRxJson" + j2735-tim-broadcast: "topic.J2735TimBroadcastJson" + pojo: + bsm: "topic.OdeBsmPojo" + spat: "topic.OdeSpatPojo" + ssm: "topic.OdeSsmPojo" + tim-broadcast: "topic.OdeTimBroadcastPojo" + bsm-during-event: "topic.OdeBsmDuringEventPojo" + rx-bsm: "topic.OdeBsmRxPojo" + rx-spat: "topic.OdeSpatRxPojo" + tx-bsm: "topic.OdeBsmTxPojo" + tx-map: "topic.OdeMapTxPojo" + tx-psm: "topic.OdePsmTxPojo" + tx-spat: "topic.OdeSpatTxPojo" + tx-srm: "topic.OdeSrmTxPojo" + raw-encoded-json: + bsm: "topic.OdeRawEncodedBSMJson" + map: "topic.OdeRawEncodedMAPJson" + psm: "topic.OdeRawEncodedPSMJson" + spat: "topic.OdeRawEncodedSPATJson" + srm: "topic.OdeRawEncodedSRMJson" + ssm: "topic.OdeRawEncodedSSMJson" + tim: "topic.OdeRawEncodedTIMJson" + sdx-depositor: + input: "topic.SDWDepositorInput" + file: + filtered-output: "/topic/filtered_messages" + unfiltered-output: "/topic/unfiltered_messages" + receivers: + generic: + buffer-size: 2000 + receiver-port: 44990 + bsm: + buffer-size: 500 + receiver-port: 46800 + map: + buffer-size: 2048 + receiver-port: 44920 + psm: + buffer-size: 500 + receiver-port: 44940 + spat: + buffer-size: 500 + receiver-port: 44910 + srm: + buffer-size: 500 + receiver-port: 44930 + ssm: + buffer-size: 500 + receiver-port: 44900 + tim: + buffer-size: 500 + receiver-port: 47900 + file-importer: + buffer-size: 500 + backup-dir: "backup" + failed-dir: "failed" + time-period: 1 + upload-location-root: "uploads" + obu-log-upload-location: "bsmlog" + tim-ingest-monitoring: + tracking-enabled: true + interval: 1 \ No newline at end of file diff --git a/jpo-sdw-depositor b/jpo-sdw-depositor index ca109a47a..0180d3024 160000 --- a/jpo-sdw-depositor +++ b/jpo-sdw-depositor @@ -1 +1 @@ -Subproject commit ca109a47a5e20776c5ddb5df98dfdce402023c9a +Subproject commit 0180d30242fdfe7c178f3e060267b8690220c473 diff --git a/jpo-security-svcs b/jpo-security-svcs index 95533c2c4..eaa5a3ab4 160000 --- a/jpo-security-svcs +++ b/jpo-security-svcs @@ -1 +1 @@ -Subproject commit 95533c2c49dd2f3327cbe4afdd658a9d3362ea7d +Subproject commit eaa5a3ab49be37c5457677840b94d674e4be5e45 diff --git a/jpo-utils b/jpo-utils index 5beea2a7a..99c36526a 160000 --- a/jpo-utils +++ b/jpo-utils @@ -1 +1 @@ -Subproject commit 5beea2a7a1dc1b25d868b3d8ef79f6292b07f819 +Subproject commit 99c36526af8c349e6ec92440cc017fffbf2c5652 From 91561527190947ec022939d9e93188b176fd885e Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 11 Nov 2024 15:48:02 -0700 Subject: [PATCH 055/264] SSM processing fix and unit test update to verify functionality --- .../ode/plugin/j2735/builders/SSMBuilder.java | 2 +- .../j2735/builders/SignalStatusBuilder.java | 35 ++++++++----------- .../builders/SignalStatusListBuilder.java | 30 ++++++++-------- .../SignalStatusPackageListBuilder.java | 35 ++++++++++--------- .../coder/OdeSsmDataCreatorHelperTest.java | 11 +++--- 5 files changed, 56 insertions(+), 57 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SSMBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SSMBuilder.java index fdcc2a688..ef3dcc8f9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SSMBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SSMBuilder.java @@ -27,7 +27,7 @@ public static J2735SSM genericSSM(JsonNode SSMMessage) { JsonNode sequenceNumber = SSMMessage.get("sequenceNumber"); if(sequenceNumber != null) { - genericSSM.setSecond(sequenceNumber.asInt()); + genericSSM.setSequenceNumber(sequenceNumber.asInt()); } JsonNode status = SSMMessage.get("status"); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusBuilder.java index f612282d6..62374dd68 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusBuilder.java @@ -6,45 +6,40 @@ import us.dot.its.jpo.ode.plugin.j2735.J2735IntersectionReferenceID; public class SignalStatusBuilder { - private SignalStatusBuilder() { + private SignalStatusBuilder() { throw new UnsupportedOperationException(); } - public static J2735SignalStatus genericSignalStatus(JsonNode statusNode) { - J2735SignalStatus signalStatus = new J2735SignalStatus(); + public static J2735SignalStatus genericSignalStatus(JsonNode statusNode) { + J2735SignalStatus signalStatus = new J2735SignalStatus(); - JsonNode sequenceNumber = statusNode.get("sequenceNumber"); - if(sequenceNumber != null) - { + JsonNode sequenceNumber = statusNode.get("sequenceNumber"); + if (sequenceNumber != null) { signalStatus.setSequenceNumber(sequenceNumber.asInt()); } - JsonNode statusId = statusNode.get("id"); - if(statusId != null) - { - J2735IntersectionReferenceID idObj = new J2735IntersectionReferenceID(); + JsonNode statusId = statusNode.get("id"); + if (statusId != null) { + J2735IntersectionReferenceID idObj = new J2735IntersectionReferenceID(); JsonNode region = statusId.get("region"); - if (region != null) - { + if (region != null) { idObj.setRegion(region.asInt()); } JsonNode refId = statusId.get("id"); - if (refId != null) - { + if (refId != null) { idObj.setId(refId.asInt()); } signalStatus.setId(idObj); } - JsonNode sigStatus = statusNode.get("sigStatus"); - if(sigStatus != null) - { - signalStatus.setSigStatus(SignalStatusPackageListBuilder.genericSignalStatusPackageList(sigStatus)); + JsonNode sigStatus = statusNode.get("sigStatus"); + if (sigStatus != null) { + signalStatus.setSigStatus(SignalStatusPackageListBuilder.genericSignalStatusPackageList(sigStatus)); } - return signalStatus; - } + return signalStatus; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java index 77639e408..61efbfe91 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java @@ -14,21 +14,21 @@ private SignalStatusListBuilder() { public static J2735SignalStatusList genericSignalStatusList(JsonNode status) { J2735SignalStatusList signalStatusList = new J2735SignalStatusList(); - if (status.isArray()) { - Iterator elements = status.elements(); - - while (elements.hasNext()) { - signalStatusList.getStatus() - .add(SignalStatusBuilder.genericSignalStatus(elements.next())); - } - } else { - JsonNode signalStatus = status.get("SignalStatus"); - if(signalStatus != null) - { - signalStatusList.getStatus() - .add(SignalStatusBuilder.genericSignalStatus(signalStatus)); - } - } + JsonNode signalStatus = status.get("SignalStatus"); + if(signalStatus != null) + { + if (signalStatus.isArray()) { + Iterator elements = signalStatus.elements(); + + while (elements.hasNext()) { + signalStatusList.getStatus() + .add(SignalStatusBuilder.genericSignalStatus(elements.next())); + } + } else { + signalStatusList.getStatus() + .add(SignalStatusBuilder.genericSignalStatus(signalStatus)); + } + } return signalStatusList; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java index 987937749..4f550cc00 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java @@ -14,22 +14,25 @@ private SignalStatusPackageListBuilder() { public static J2735SignalStatusPackageList genericSignalStatusPackageList(JsonNode sigStatus) { J2735SignalStatusPackageList signalStatusPackageList = new J2735SignalStatusPackageList(); - if (sigStatus.isArray()) { - Iterator elements = sigStatus.elements(); - - while (elements.hasNext()) { - signalStatusPackageList.getSigStatus() - .add(SignalStatusPackageBuilder.genericSignalStatusPackage(elements.next())); - } - } else { - JsonNode signalStatusPackage = sigStatus.get("SignalStatusPackage"); - if(signalStatusPackage != null) - { - signalStatusPackageList.getSigStatus() - .add(SignalStatusPackageBuilder.genericSignalStatusPackage(signalStatusPackage)); - } - - } + JsonNode signalStatusPackage = sigStatus.get("SignalStatusPackage"); + if(signalStatusPackage != null) + { + if (signalStatusPackage.isArray()) { + Iterator elements = signalStatusPackage.elements(); + + while (elements.hasNext()) { + signalStatusPackageList.getSigStatus() + .add(SignalStatusPackageBuilder.genericSignalStatusPackage(elements.next())); + } + } else { + signalStatusPackageList.getSigStatus() + .add(SignalStatusPackageBuilder.genericSignalStatusPackage(signalStatusPackage)); + + } + } + else { + return null; + } return signalStatusPackageList; } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeSsmDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeSsmDataCreatorHelperTest.java index 014176828..b80be1360 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeSsmDataCreatorHelperTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeSsmDataCreatorHelperTest.java @@ -1,12 +1,11 @@ package us.dot.its.jpo.ode.coder; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.junit.jupiter.api.Test; -import com.fasterxml.jackson.databind.JsonNode; - import us.dot.its.jpo.ode.model.OdeSsmData; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; @@ -20,17 +19,19 @@ public void testConstructor() { @Test public void testCreateOdeSrmData() { - String consumedData = "us.dot.its.jpo.ode.model.OdeAsn1Payload50b5374e-db5b-410f-84d8-c047b157119010002021-10-03T20:00:43.331224Z60falsessmTxunsecuredDataMessageFrameUPER172.250.250.77RSUMessageFrame30001211023668450943023"; - JsonNode jsonMap = null; + String consumedData = "ssmTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload75b0ddae-5f6e-403d-ae9d-ec41080bb50010002024-11-11T21:42:11.755Z70RSUfalse001E2366CF218CA0B40010BD4C2896A131B71C0450201685AD512AACB3B0105010402E4C6A805000172.18.0.1RSUMessageFrame30446241360009021211528235811271105413231435923970101551597"; try { - jsonMap = XmlUtils.toObjectNode(consumedData); + XmlUtils.toObjectNode(consumedData); } catch (XmlUtilsException e) { fail("XML parsing error:" + e); } + + String expectedJson = "{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeSsmPayload\",\"serialId\":{\"streamId\":\"75b0ddae-5f6e-403d-ae9d-ec41080bb500\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-11-11T21:42:11.755Z\",\"schemaVersion\":7,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001E2366CF218CA0B40010BD4C2896A131B71C0450201685AD512AACB3B0105010402E4C6A805000\",\"originIp\":\"172.18.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"data\":{\"timeStamp\":446241,\"second\":36000,\"sequenceNumber\":90,\"status\":{\"signalStatus\":[{\"sequenceNumber\":2,\"id\":{\"id\":12115},\"sigStatus\":{\"signalStatusPackage\":[{\"requester\":{\"id\":{\"stationID\":2823581127},\"request\":1,\"sequenceNumber\":10,\"role\":\"publicTransport\"},\"inboundOn\":{\"lane\":5},\"duration\":41323,\"status\":\"rejected\"},{\"requester\":{\"id\":{\"stationID\":1435923970},\"request\":10,\"sequenceNumber\":1,\"role\":\"publicTransport\"},\"inboundOn\":{\"lane\":5},\"duration\":51597,\"status\":\"rejected\"}]}}]}},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735SSM\"}}"; OdeSsmData ssmData; try { ssmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData); assertNotNull(ssmData); + assertEquals(ssmData.toJson(), expectedJson); } catch (XmlUtilsException e) { e.printStackTrace(); } From 6538eac93fce4b9c230b0640287dbeca0af4013e Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 14 Nov 2024 15:16:50 -0700 Subject: [PATCH 056/264] Extract environment variables from OdeProperties into Spring Configuration objects (#113) * Migrate kafka configuration values to ODEKafkaProperties This is the first part of the work needed to separate the OdeProperties into multpile more manageable chunks. It introduces the usage of application.yaml and @Autowired in tests to more fully utilize the Spring framework. * remove @Component annotation and accept linter errors Adding the @Component annotation to the *Receivers caused double instantiations and port binding issues * migrate from application.properties to application.yaml and introducde host-ip config val * add make restart target for easier, faster restarts that don't require a full image rebuild * add missing getHostId test for odekafkaproperties * move odekafkaproperties to kafka package * correctly declare restart target as PHONY in Makefile * move OdeKafkaPropertiesTest to correct test package * add tests to OdePropertiesTest for hostIP and remove unused imports and variables * moved hostID from OdeKafkaProperties to AppContext to keep scope of new class small and directed * correct application.yaml's disabled-topics block * correct formatting in Asn1*JSONTest.java files and fix Sonarlint errors All swaps of argument positions in the mentioned tests are to align the function calls to the defition: assert*(expected, actual). Before this swap, the call was made in the tests like assert*(actual, expected) which has the same outcome when tests *pass* but is confusing when tests do not pass because the failure output will have the actual and expected values swapped in the message. * replace complex if-else nest with simpler switch statments in decoded data router * extract BSM properties from OdeProperties * correct application.yaml indentation for bsm block * reformat GenericReceiver * if-else to switch and pull logic out of nested if-block where possible * define topics structure in application.yaml * convert MessagePublisher to interface and implement in existing publishers * ImporterDirectoryWatcher properties and necessary refactors for related classes * Complete refactoring of UdpServicesController w/ intro of UDPReceiverProperties * add sprint.http.multipart config values to application.yaml * Add TODO for @mcook42 to update README.md with corrected instructions once OdeProperties refactor is completed * remove remaining references to kafka properties from OdeProperties * remove dead test code and add missing constructor param to ImporterDirectoryWatcherTest.java * finalize application.yaml topics structure and config classes * asn1decoder flows updated with new configuration objects * asn1encoder flows updated with new configuration objects * FileSystemStorageService refactor to use new configuration properties * delete unused BSMReceiverPropertiesTest.java * File-related controllers and watchers corrected for new configuration objects * Update TimDepositController with new topics configs * ByteArrayPublisher correct config usage * TimTransmorgrifierTest corrections * LogFileToAsn1CodecPublisherTest corrections * Revert "TimTransmorgrifierTest corrections" This reverts commit 2a27569087ce82d9e392bb1eb67ff26fcc04f7a7. * Trivial JMockit test fixes via \@Inject annotations * update test application.yaml * test application.yaml and OdeKafkaPropertiesTest correction * explicitly initialize OdeDataPublisher in OdeDataPublisherTest to avoid JMockit limitations with Set mocking * Adjust ImporterDirectoryWatcherTest.java to confirm directory creation instead of trying to run .run() It doesn't make much sense to test the scheduledExecutor when we already have a test suite for the ImporterProcessor called by the scheduled executor. JMockit doesn't play nicely (easily) with Spring configuration objects, so in the interest of time I refactored this test suite to confirm that we create the necessary directories without the use of JMockit. * OdeStringPublisherTest corrections to avoid JMockit Set mocking limitations * Replace unintentionally deleted license header in MessagePublisher * remove unnecessary comments from UdpServicesController * added missing tests for new configs in kafka package * reformatted LogFileToAsn1CodecPublisher for readability * pull RSUProperties up and refactor tests for clarity in OdePropertiesTest and TimTransmogrifierTest * remove redundant @Value annotations from OdeKafkaProperties * add missing AbstractUdpReceiverPublisher slf4j annotation * typo fixes, renames, and comment correction for LogFileToAsn1CodecPublisher and RSUProperties * remove dead/incorrect comment from TimDepositController * pull kafka env vars into OdeKafkaProperties * update SerializableMessageProducerPoolTest to use Spring and JUnit Jupiter for consistent and easier testing * standardize bean injection of RSU in OdeProperties * allow for use of fixed instant clock in DateTimeUtils to enable usage in unit tests * extract RsuProperties from OdeProperties and pull DATA_SIGNING_ENABLED_RSU var into application.yaml * extract SecurityServicesProperties and add SecurityServicesPropertiesValidator validation * test SecurityServicesProperties and add default values from comment in sample.env * implement CustomConversionServiceConfig to provide conversion of empty environment variables for Integer properties * remove unused KAFKA_TYPE from application.yaml * correct warnings in Dockerfile - maintainer -> label and no-cache * add **/.*iml to .gitignore * add validation to OdeKafkaProperties after runtime exception was thrown during testing * remove all dead references to OdeProperties from various files * Update README.md and UserGuide.md with new app configuration instructions. I removed the dead/outdated configuration table from UserGuide.md in favor of the self-documenting configuration objects and their Validation classes. This will keep the code and available configuration values up-to-date automatically instead of requiring developers to maintain these both in code and in documentation. * Asn1CommandManagerTest and SecurityServicesPropertiesValidator test updates for better validation * add @Import annotation to InetPacketSenderTest to ensure EventLogger is available during test runs * correct the OdeKafkaProperties validation * remove unused ppm.properties file * undo duplicate code extraction into function - makes code less clear, and is untested, so best to return to how it was * undo star imports in SnmpSession * use assertThrows instead of catching and asserting exception class in TimTransmogrifierTest * correct typo in TimDepositController comment, remove getters and setters from SerializableMessageProducerPool * add slf4j annotation to ImporterProcessor * use the correct environment variable names for tim-ingest-monitoring in application.yaml * add @Import annotation to InetPacketSenderTest to ensure EventLogger is available during test runs * replace EventLogger with slf4j logger in InetPacketSenderTest * replace EventLogger with slf4j logger in InetPacketSender * remove unused imports from InetPacketSenderTest * move OdeTimJsonTMCFiltered topic from OdeProperties to JsonTopics after merge * move compression type into OdeKafkaProperties * use defaults from MessageProducer in OdeKafkaProperties for consistency * OdeTimJsonTopologyTest remove unnecessary public access modifiers * removed old git artifact RSUProperties superseded by RsuProperties --- .gitignore | 4 +- Dockerfile | 10 +- README.md | 25 +- docs/UserGuide.md | 72 +- .../dot/its/jpo/ode/util/DateTimeUtils.java | 19 +- .../jpo/ode/util/SerializableObjectPool.java | 8 +- .../jpo/ode/inet/InetPacketSenderTest.java | 25 +- .../its/jpo/ode/wrapper/MessageProducer.java | 100 +-- .../src/main/resources/application.properties | 0 .../us/dot/its/jpo/ode/OdeProperties.java | 59 +- .../dot/its/jpo/ode/OdeSvcsApplication.java | 2 +- .../ode/SerializableMessageProducerPool.java | 162 ++-- .../its/jpo/ode/coder/ByteArrayPublisher.java | 2 +- .../jpo/ode/coder/FileAsn1CodecPublisher.java | 12 +- .../its/jpo/ode/coder/OdeDataPublisher.java | 2 - .../config/CustomConversionServiceConfig.java | 24 + .../ode/config/StringToIntegerConverter.java | 18 + .../its/jpo/ode/kafka/OdeKafkaProperties.java | 19 +- .../kafka/OdeKafkaPropertiesValidator.java | 32 + .../us/dot/its/jpo/ode/rsu/RsuDepositor.java | 272 ++++--- ...{RSUProperties.java => RsuProperties.java} | 4 +- .../dot/its/jpo/ode/rsu/RsuResponseCode.java | 14 + .../security/SecurityServicesProperties.java | 28 + .../SecurityServicesPropertiesValidator.java | 51 ++ .../ode/services/asn1/Asn1CommandManager.java | 17 +- .../services/asn1/Asn1DecodedDataRouter.java | 14 +- .../services/asn1/Asn1EncodedDataRouter.java | 37 +- .../asn1/AsnCodecRouterServiceController.java | 25 +- .../asn1/message/Asn1DecodeBSMJSON.java | 2 +- .../asn1/message/Asn1DecodeMAPJSON.java | 2 +- .../asn1/message/Asn1DecodePSMJSON.java | 2 +- .../asn1/message/Asn1DecodeSPATJSON.java | 2 +- .../asn1/message/Asn1DecodeSRMJSON.java | 2 +- .../asn1/message/Asn1DecodeSSMJSON.java | 2 +- .../asn1/message/Asn1DecodeTIMJSON.java | 2 +- .../ode/services/json/ToJsonConverter.java | 2 +- .../us/dot/its/jpo/ode/snmp/SnmpSession.java | 727 +++++++++--------- .../ode/storage/FileSystemStorageService.java | 20 +- .../jpo/ode/traveler/TimDeleteController.java | 13 +- .../ode/traveler/TimDepositController.java | 25 +- .../jpo/ode/traveler/TimQueryController.java | 283 ++++--- .../jpo/ode/traveler/TimTransmogrifier.java | 8 +- .../ode/udp/AbstractUdpReceiverPublisher.java | 4 +- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 8 +- .../jpo/ode/udp/generic/GenericReceiver.java | 2 +- .../dot/its/jpo/ode/udp/map/MapReceiver.java | 7 +- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 5 +- .../its/jpo/ode/udp/spat/SpatReceiver.java | 7 +- .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 27 +- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 8 +- .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 2 +- .../src/main/resources/application.yaml | 23 +- .../us/dot/its/jpo/ode/OdePropertiesTest.java | 45 +- .../SerializableMessageProducerPoolTest.java | 130 +--- .../jpo/ode/coder/ByteArrayPublisherTest.java | 4 +- .../ode/exporter/StompStringExporterTest.java | 3 - .../ode/importer/ImporterProcessorTest.java | 5 - .../jpo/ode/kafka/OdeKafkaPropertiesTest.java | 58 +- .../OdeKafkaPropertiesValidatorTest.java | 60 ++ .../dot/its/jpo/ode/rsu/RsuDepositorTest.java | 90 +-- .../SecurityServicesPropertiesTest.java | 54 ++ ...curityServicesPropertiesValidatorTest.java | 72 ++ .../services/asn1/Asn1CommandManagerTest.java | 13 +- .../asn1/Asn1DecodedDataRouterTest.java | 6 - .../asn1/Asn1EncodedDataRouterTest.java | 8 +- .../AsnCodecRouterServiceControllerTest.java | 11 +- .../asn1/message/Asn1DecodeMAPJSONTest.java | 1 - .../asn1/message/Asn1DecodeSRMJSONTest.java | 1 - .../asn1/message/Asn1DecodeSSMJSONTest.java | 1 - .../asn1/message/Asn1DecodeTIMJSONTest.java | 1 - .../AsnCodecMessageServiceControllerTest.java | 1 - .../services/json/ToJsonConverterTest.java | 5 +- .../json/ToJsonServiceControllerTest.java | 1 - .../dot/its/jpo/ode/snmp/SnmpSessionTest.java | 2 - .../storage/FileSystemStorageServiceTest.java | 2 +- .../ode/traveler/TimDeleteControllerTest.java | 12 +- .../traveler/TimDepositControllerTest.java | 8 +- .../ode/traveler/TimQueryControllerTest.java | 28 +- .../ode/traveler/TimTransmogrifierTest.java | 497 ++++++------ .../ode/upload/FileUploadControllerTest.java | 7 - .../jpo/ode/wrapper/MessageProducerTest.java | 1 - .../src/test/resources/application.yaml | 22 +- ppm.properties | 35 - 83 files changed, 1700 insertions(+), 1726 deletions(-) delete mode 100644 jpo-ode-core/src/main/resources/application.properties create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/CustomConversionServiceConfig.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/StringToIntegerConverter.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/{RSUProperties.java => RsuProperties.java} (93%) create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuResponseCode.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidator.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidatorTest.java diff --git a/.gitignore b/.gitignore index 436aa2d2d..2f3388c2c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ /SNMP_Error.log /Events.log /uploads -*.iml +**/*.iml *.DS_Store SNMP_Error.log Events.log @@ -132,4 +132,4 @@ settings.xml ######################### ### jpo-cvdp ### -ppm_data/* \ No newline at end of file +ppm_data/* diff --git a/Dockerfile b/Dockerfile index 097312db7..74e620955 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ -FROM maven:3.8-eclipse-temurin-21-alpine as builder -MAINTAINER 583114@bah.com +FROM maven:3.8-eclipse-temurin-21-alpine AS builder +LABEL org.opencontainers.image.authors="583114@bah.com" WORKDIR /home @@ -25,8 +25,8 @@ COPY --from=builder /home/jpo-ode-svcs/src/main/resources/logback.xml /home COPY --from=builder /home/jpo-ode-svcs/target/jpo-ode-svcs.jar /home COPY ./scripts/startup_jpoode.sh /home -RUN apk add openssh -RUN apk add openrc -RUN rc-update add sshd +RUN apk --no-cache add openssh \ + && apk --no-cache add openrc \ + && rc-update add sshd ENTRYPOINT ["sh", "/home/startup_jpoode.sh"] diff --git a/README.md b/README.md index 17ea98a7b..2ae921377 100644 --- a/README.md +++ b/README.md @@ -206,13 +206,13 @@ git config --global core.autocrlf false The ODE software system consists of the following modules hosted in separate Github repositories: -|Name|Visibility|Description| -|----|----------|-----------| -|[jpo-ode](https://github.com/usdot-jpo-ode/jpo-ode)|public|Contains the public components of the application code.| -|[jpo-cvdp](https://github.com/usdot-jpo-ode/jpo-cvdp)|public|Privacy Protection Module| -|[asn1_codec](https://github.com/usdot-jpo-ode/asn1_codec)|public|ASN.1 Encoder/Decoder module| -|[jpo-security-svcs](https://github.com/usdot-jpo-ode/jpo-security-svcs)|public|Provides cryptographic services.| -|[jpo-sdw-depositor](https://github.com/usdot-jpo-ode/jpo-sdw-depositor)|public|SDW depositor service. Optional, can be enabled by using the `COMPOSE_PROFILES` environmental variable| +| Name | Visibility | Description | +|-------------------------------------------------------------------------|------------|--------------------------------------------------------------------------------------------------------| +| [jpo-ode](https://github.com/usdot-jpo-ode/jpo-ode) | public | Contains the public components of the application code. | +| [jpo-cvdp](https://github.com/usdot-jpo-ode/jpo-cvdp) | public | Privacy Protection Module | +| [asn1_codec](https://github.com/usdot-jpo-ode/asn1_codec) | public | ASN.1 Encoder/Decoder module | +| [jpo-security-svcs](https://github.com/usdot-jpo-ode/jpo-security-svcs) | public | Provides cryptographic services. | +| [jpo-sdw-depositor](https://github.com/usdot-jpo-ode/jpo-sdw-depositor) | public | SDW depositor service. Optional, can be enabled by using the `COMPOSE_PROFILES` environmental variable | You may download the stable, default branch for ALL of these dependencies by using the following recursive git clone command: @@ -402,18 +402,15 @@ The only requirement for deploying `asn1_codec` module on Docker is the setup of To run the ODE with PPM module, you must install and start the PPM service. PPM service communicates with other services through Kafka Topics. PPM will read from the specified "Raw BSM" topic and publish the result to the specified "Filtered Bsm" topic. These topic names are specified by the following ODE and PPM properties: -[//]: # ((TODO(@mcook42): Once the application.yaml file is updated with the correct properties at the end of the OdeProperties refactor effort, update the following list with the correct instructions)) - - ODE properties for communications with PPM (set in application.yaml) - - ode.kafkaTopicOdeBsmJson (default = topic.OdeBsmJson) - - ode.kafkaTopicFilteredOdeBsmJson (default = topic.FilteredOdeBsmJson) + - ODE properties for communications with PPM (set in [application.yaml](jpo-ode-svcs/src/main/resources/application.yaml)) + - ode.kafka.topics.json.bsm (default = topic.OdeBsmJson) + - ode.kafka.topics.json.bsm-filtered (default = topic.FilteredOdeBsmJson) - PPM properties for communications with ODE (set in yourconfig.properties) - privacy.topic.consumer (default = j2735BsmRawJson) - privacy.topic.producer (default = j2735BsmFilteredJson) Follow the instructions [here](https://github.com/usdot-jpo-ode/jpo-cvdp/blob/master/docs/installation.md) to install and build the PPM service. -During the build process, edit the sample config file located in `config/example.properties` and point the property `metadata.broker.list` towards the host of your docker machine or wherever the kafka brokers are hosted. You may use the command `docker-machine ls` to find the kafka service. - After a successful build, use the following commands to configure and run the PPM ```bash @@ -547,7 +544,7 @@ Install the IDE of your choice: ### Dev Container Environment -The project can be reopened inside of a dev container in VSCode. This environment should have all of the necessary dependencies to debug the ODE and its submodules. When attempting to run scripts in this environment, it may be necessary to make them executable with "chmod +x" first. +The project can be reopened inside a dev container in VSCode. This environment should have all the necessary dependencies to debug the ODE and its submodules. When attempting to run scripts in this environment, it may be necessary to make them executable with "chmod +x" first. [Back to top](#table-of-contents) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8929e562c..2cea591bd 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -353,73 +353,13 @@ and deploying the JPO-ODE services. #### 6.6.4 - ODE Application Properties -[//]: # ((TODO(@mcook42): Once the application.yaml file is updated with the correct properties at the end of the OdeProperties refactor effort, update the following list with the correct instructions)) -JPO ODE configuration can be modified in a number of ways. +JPO ODE configuration is managed through the [application.yaml](../jpo-ode-svcs/src/main/resources/application.yaml). +Many of the configuration values in the application.yaml are derived from environment variables. +It is recommended that you set these properties from your system environment variables in your .env file. +See [sample.env](../sample.env) for examples and variable names. -1. You can specify the configuration parameters in a file named - _application.yaml_ located in the same directory from which - the application is launched. - -2. You may specify properties as command line options in the form of - -```bash ---ode.propertyName=propertyValue -``` - -For example, add - -```bash ---ode.uploadLocation=myUploadFolder -``` - -3. _You may_ specify properties as system environment variables in the - form of _ode.sdwApiKey=12345_ - -Other properties not specific to the ODE can also be defined in a -similar way but without the _ode_ prefix. - -Current ODE properties and their default are defined in OdeProperties -class. The property name is the name of the OdeProperties class instance -parameter. - -The following table describes all the ODE properties currently -available. - -_Table 1 - ODE Application Properties_ - -| Name | Default Value | Required | Description | -|------------------------------------------|-----------------------------------------------------------------------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| ode.kafkaBrokers | $DOCKER_HOST_IP:9092 | X | List of kafka brokers and ports | -| ode.uploadLocationRoot | ./uploads | | Location of the shared directory where ODE monitors for files to ingest. | -| ode.uploadLocationObuLog | ./uploads/bsmlog | | Specific location for OBU log files with header fields to specify direction, UTC timestamp, and other metadata | -| ode.pluginsLocations | ./plugins | | Location of the jar files for ODE plugins. | -| ode.kafkaProducerType | async | | Specifies whether publishing to Kafka will be synchronous (i.e. blocking until the data has been persisted) or asynchronous (i.e. publish and forget). Valid values are: sync or async. Sync will generally be slower but more reliable, async is faster with the risk of losing data if kafka crashes during the write operation. | -| ode.sdcIp | 104.130.170.234 | | IPv4 address of SDC | -| ode.sdcPort | 46753 | | Destination port of SDC | -| ode.bsmReceiverPort | 46800 | | The UDP port that ODE will use to listen to BSM messages. | -| ode.bsmBufferSize | 500 | | Size of the buffer allocated for receiving BSM messages through UDP interface | -| ode. kafkaTopicVsdPojo | AsnVsdPojo | | The topic that contains VSDs if ode.enabledVsdKafkaTopic is enabled. | -| ode.vsdBufferSize | 500 | | Size of the buffer allocated for receiving VSD messages through UDP interface | -| ode.vsdReceiverPort | 46753 | | The UDP port that ODE will use to listen to VSD messages. | -| ode.vsdDepositorPort | 5555 | | The UDP port that ODE will use to send VSD messages to SDC for deposit. | -| ode.vsdTrustport | 5556 | | The UDP port that ODE will use to establish trust with the SDC for VSD messages. | -| ode.caCertPath | | | | -| | null | X | path/to/CaCertFile or define env variable ${ODE_CA_CERT_PATH} | -| ode.selfCertPath | null | X | path/to/selfCertFile or define env variable ${ODE_SELF_CERT_PATH} | -| ode.selfPrivateKeyReconstructionFilePath | null | X | path/to/selfPrivateKeyReconstructionFile or define env variable ${ODE_SELF_PRIVATE_KEY_RECONSTRUCTION_FILE_PATH} | -| ode.selfSigningPrivateKeyFilePath | null | X | path/to/selfSigningPrivateKeyFile or define env variable ${ODE_SELF_SIGNING_PRIVATE_KEY_FILE_PATH} | -| ode.isdBufferSize | 500 | | Size of the buffer allocated for receiving ISD messages through UDP interface | -| ode.isdReceiverPort | 46801 | | The UDP port that ODE will use to listen to ISD messages. | -| ode.isdDepositorPort | 6666 | | The UDP port that ODE will use to send ISD messages to SDC for deposit. | -| ode.isdTrustPort | 6667 | | The UDP port that ODE will use to establish trust with the SDC for ISD messages. | -| ode.dataReceiptBufferSize | null | | Size of the buffer allocated for receiving ISD receipt messages through UDP interface | -| ode.depositSanitizedBsmToSdc | false | | Enable/disable packaging of BSMs into VSDs and depositing VSDs to SDC | -| ode.serviceRespExpirationSeconds | 10 | | Number of seconds the trust manager will wait to receive service request response before timing out. | -| Kafka Topics | See Section 8.3.1.1 | | See Section 8.3.1.1 | -| ode.securitySvcsSignatureUri | null | | The URI for signing data using the jpo-security-svcs module. Normally doesn't need to be set because ODE will calculate it based on DOCKER_HOST_IP. If the service is deployed outside Docker, it should be set to of the server it's running on. If you do not want to sign the data set this property to UNSECURED. | -| ode.rsuUsername | null | If not present in JSON | The SNMP username used to authenticate with an RSU when depositing, deleting, or querying TIMs. | -| ode.rsuPassword | null | If not present in JSON | The SNMP password used to authenticate with an RSU when depositing, deleting, or querying TIMs. | -| ode.kafkaTopicsDisabled | topic.OdeBsmRxPojo, topic.OdeBsmTxPojo, topic.OdeBsmDuringEventPojo,topic.OdeTimBroadcastPojo | | List of topics to be disabled from publishing. | +See [Spring Boot's Externalized Configuration documentation](https://docs.spring.io/spring-boot/reference/features/external-config.html) +for more information on how to use the application.yaml file and how to override the default values.
diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/DateTimeUtils.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/DateTimeUtils.java index 7dea6140e..7ddaa79c7 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/DateTimeUtils.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/DateTimeUtils.java @@ -16,24 +16,27 @@ package us.dot.its.jpo.ode.util; import java.text.ParseException; -import java.time.Instant; -import java.time.ZoneId; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; +import java.time.*; import java.time.format.DateTimeFormatter; import java.util.Date; public class DateTimeUtils { + private static Clock clock = Clock.systemUTC(); + private DateTimeUtils() { } + public static void setClock(Clock clock) { + DateTimeUtils.clock = clock; + } + public static String now() { return nowZDT().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); } public static ZonedDateTime nowZDT() { - return ZonedDateTime.now(ZoneId.of("UTC")); + return ZonedDateTime.now(clock.withZone(ZoneId.of("UTC"))); } public static String isoDateTime(ZonedDateTime zonedDateTime) { @@ -45,7 +48,7 @@ public static String isoDateTime(ZonedDateTime zonedDateTime) { return ZonedDateTime.of(year, month, dayOfMonth, hourOfDay, minute, second, millisec * 1000000, ZoneOffset.UTC); } - public static ZonedDateTime isoDateTime(String s) throws ParseException { + public static ZonedDateTime isoDateTime(String s) { return ZonedDateTime.parse(s); } @@ -53,8 +56,8 @@ public static ZonedDateTime isoDateTime(Date date) { return ZonedDateTime.from(date.toInstant().atZone(ZoneId.of("UTC"))); } - public static ZonedDateTime isoDateTime(long epockMillis) { - return ZonedDateTime.ofInstant(Instant.ofEpochMilli(epockMillis), ZoneId.of("UTC")); + public static ZonedDateTime isoDateTime(long epochMillis) { + return ZonedDateTime.ofInstant(Instant.ofEpochMilli(epochMillis), ZoneId.of("UTC")); } public static boolean diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/SerializableObjectPool.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/SerializableObjectPool.java index 85849305a..50d44685b 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/SerializableObjectPool.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/SerializableObjectPool.java @@ -26,10 +26,10 @@ public abstract class SerializableObjectPool implements Serializable { private Hashtable locked, unlocked; - public SerializableObjectPool() { + protected SerializableObjectPool() { expirationTime = 30000; // 30 seconds - locked = new Hashtable(); - unlocked = new Hashtable(); + locked = new Hashtable<>(); + unlocked = new Hashtable<>(); } protected abstract T create(); @@ -41,7 +41,7 @@ public SerializableObjectPool() { public synchronized T checkOut() { long now = System.currentTimeMillis(); T t; - if (unlocked.size() > 0) { + if (!unlocked.isEmpty()) { Enumeration e = unlocked.keys(); while (e.hasMoreElements()) { t = e.nextElement(); diff --git a/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java b/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java index b2ecc8a42..05b8e331e 100644 --- a/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java +++ b/jpo-ode-common/src/test/java/us/dot/its/jpo/ode/inet/InetPacketSenderTest.java @@ -15,12 +15,11 @@ ******************************************************************************/ package us.dot.its.jpo.ode.inet; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.util.CodecUtils; import java.io.IOException; import java.net.DatagramPacket; @@ -31,14 +30,12 @@ import java.net.UnknownHostException; import java.util.Arrays; -import lombok.extern.slf4j.Slf4j; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import mockit.Capturing; -import us.dot.its.jpo.ode.util.CodecUtils; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; @Slf4j public class InetPacketSenderTest { diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index 37834d700..d52ab3315 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -15,23 +15,23 @@ ******************************************************************************/ package us.dot.its.jpo.ode.wrapper; -import java.util.Properties; -import java.util.Set; -import org.apache.kafka.clients.producer.Callback; +import lombok.Getter; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.ProducerRecord; -import org.apache.kafka.clients.producer.RecordMetadata; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; + +import java.util.Properties; +import java.util.Set; /** - * @author 572682 - * This class encapsulates a message produce function. - * * @param Message Key type * @param Message Value type + * @author 572682 + * This class encapsulates a message produce function. */ +@Slf4j public class MessageProducer { public static final String SERIALIZATION_STRING_SERIALIZER = "org.apache.kafka.common.serialization.StringSerializer"; @@ -43,10 +43,9 @@ public class MessageProducer { public static final String DEFAULT_PRODUCER_ACKS = "all"; public static final String COMPRESSION_TYPE = "zstd"; - private static Logger logger = LoggerFactory.getLogger(MessageProducer.class); - - private Producer producer; - private Set disabledTopicsSet; + @Getter + private final Producer producer; + private final Set disabledTopicsSet; public static MessageProducer defaultByteArrayMessageProducer( String brokers, @@ -74,7 +73,7 @@ public static MessageProducer defaultStringMessageProducer( public MessageProducer( String brokers, - String type, + String kafkaType, String partitionerClass, String valueSerializerFQN, Set disabledTopics) { @@ -83,7 +82,7 @@ public MessageProducer( if (brokers != null) { props.put("bootstrap.servers", brokers); } else { - logger.error("Bootstrap servers setting is null"); + log.error("Bootstrap servers setting is null"); } props.put("key.serializer", SERIALIZATION_STRING_SERIALIZER); @@ -100,21 +99,20 @@ public MessageProducer( props.put("partitioner.class", partitionerClass); } - String kafkaType = System.getenv("KAFKA_TYPE"); if (kafkaType != null && kafkaType.equals("CONFLUENT")) { addConfluentProperties(props); } - + producer = new KafkaProducer<>(props); this.disabledTopicsSet = disabledTopics; - logger.info("Producer Created with default properties"); + log.info("Producer Created with default properties"); } public MessageProducer( String brokers, - String type, + String kafkaType, String partitionerClass, Properties props, Set enabledTopics) { @@ -123,17 +121,16 @@ public MessageProducer( if (partitionerClass != null) { props.put("partitioner.class", partitionerClass); } - - String kafkaType = System.getenv("KAFKA_TYPE"); + if (kafkaType != null && kafkaType.equals("CONFLUENT")) { addConfluentProperties(props); } - + producer = new KafkaProducer<>(props); this.disabledTopicsSet = enabledTopics; - logger.info("Producer Created"); + log.info("Producer Created"); } private Properties setDefaultProperties() { @@ -156,7 +153,7 @@ private Properties setDefaultProperties() { return props; } - private Properties addConfluentProperties(Properties props) { + private void addConfluentProperties(Properties props) { props.put("ssl.endpoint.identification.algorithm", "https"); props.put("security.protocol", "SASL_SSL"); props.put("sasl.mechanism", "PLAIN"); @@ -166,15 +163,13 @@ private Properties addConfluentProperties(Properties props) { if (username != null && password != null) { String auth = "org.apache.kafka.common.security.plain.PlainLoginModule required " + - "username=\"" + username + "\" " + - "password=\"" + password + "\";"; + "username=\"" + username + "\" " + + "password=\"" + password + "\";"; props.put("sasl.jaas.config", auth); - } - else { - logger.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); + } else { + log.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); } - return props; } public void send(String topic, K key, V value) { @@ -187,18 +182,15 @@ public void send(String topic, K key, V value) { producer.send( data, - new Callback() { - @Override - public void onCompletion(RecordMetadata returnMetadata, Exception e) { - if (null != e) { - logger.error("Error sending record.", e); - } else { - logger.debug( - "Completed publish to topic: {}, offset: {}, partition: {}", - returnMetadata.topic(), - returnMetadata.offset(), - returnMetadata.partition()); - } + (returnMetadata, e) -> { + if (null != e) { + log.error("Error sending record.", e); + } else { + log.debug( + "Completed publish to topic: {}, offset: {}, partition: {}", + returnMetadata.topic(), + returnMetadata.offset(), + returnMetadata.partition()); } }); } @@ -206,29 +198,17 @@ public void onCompletion(RecordMetadata returnMetadata, Exception e) { public void close() { producer.close(); - logger.info("Producer Closed"); - } - - public Producer getProducer() { - return producer; - } - - public MessageProducer setProducer(Producer producer) { - this.producer = producer; - return this; + log.info("Producer Closed"); } public void send(ProducerRecord producerRecord) { producer.send( producerRecord, - new Callback() { - @Override - public void onCompletion(RecordMetadata returnMetadata, Exception e) { - if (null != e) { - logger.error("Error sending record.", e); - } else { - logger.debug("Record metadata: {}", returnMetadata); - } + (returnMetadata, e) -> { + if (null != e) { + log.error("Error sending record.", e); + } else { + log.debug("Record metadata: {}", returnMetadata); } }); } diff --git a/jpo-ode-core/src/main/resources/application.properties b/jpo-ode-core/src/main/resources/application.properties deleted file mode 100644 index e69de29bb..000000000 diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index bc77354e4..626f3af9c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -21,46 +21,17 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.info.BuildProperties; -import org.springframework.context.EnvironmentAware; -import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; import us.dot.its.jpo.ode.model.OdeMsgMetadata; -import us.dot.its.jpo.ode.rsu.RSUProperties; @Configuration @ConfigurationProperties(prefix = "ode") @Data @Slf4j -public class OdeProperties implements EnvironmentAware { +public class OdeProperties { - @Autowired - private Environment env; - - /* - * General Properties - */ private int outputSchemaVersion; - private String pluginsLocations; - private String hostIP; - private boolean verboseJson; - - /* - * Security Services Module Properties - */ - private String securitySvcsSignatureUri; - private int securitySvcsPort; - private String securitySvcsSignatureEndpoint; - - /* - * Security Properties - */ - private String caCertPath; - private String selfCertPath; - private String selfPrivateKeyReconstructionFilePath; - private String selfSigningPrivateKeyFilePath; - private static final byte[] JPO_ODE_GROUP_ID = "jode".getBytes(); @Autowired @@ -72,37 +43,9 @@ void initialize() { log.info("artifactId: {}", buildProperties.getArtifact()); log.info("version: {}", buildProperties.getVersion()); OdeMsgMetadata.setStaticSchemaVersion(this.outputSchemaVersion); - - // URI for the security services /sign endpoint - if (securitySvcsSignatureUri == null) { - securitySvcsSignatureUri = "http://" + hostIP + ":" + securitySvcsPort + "/" - + securitySvcsSignatureEndpoint; - } } public String getVersion() { return buildProperties.getVersion(); } - - public String getProperty(String key) { - return env.getProperty(key); - } - - public String getProperty(String key, String defaultValue) { - return env.getProperty(key, defaultValue); - } - - public Object getProperty(String key, int i) { - return env.getProperty(key, Integer.class, i); - } - - @Override - public void setEnvironment(Environment environment) { - env = environment; - } - - @Bean - public RSUProperties rsuProperties() { - return new RSUProperties(); - } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java index a6c45ad5f..f16003ae2 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeSvcsApplication.java @@ -41,7 +41,7 @@ import org.springframework.context.annotation.Bean; @SpringBootApplication -@EnableConfigurationProperties(OdeProperties.class) +@EnableConfigurationProperties public class OdeSvcsApplication { static final int DEFAULT_NO_THREADS = 10; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java index c7cce0f03..ce1bef40a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,112 +15,64 @@ ******************************************************************************/ package us.dot.its.jpo.ode; -import java.util.Properties; - import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.util.SerializableObjectPool; import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class SerializableMessageProducerPool extends SerializableObjectPool> { - - private static final long serialVersionUID = -2293786403623236678L; - - transient OdeProperties odeProperties; - transient OdeKafkaProperties odeKafkaProperties; - - private String brokers; - private String type; - private String partitionerClass; - - private Properties props; - - public SerializableMessageProducerPool(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties) { - super(); - this.odeProperties = odeProperties; - this.odeKafkaProperties = odeKafkaProperties; - this.brokers = odeKafkaProperties.getBrokers(); - this.type = odeKafkaProperties.getProducerType(); - this.partitionerClass = odeProperties.getProperty("kafka.partitionerClass"); - init(); - } - - public SerializableMessageProducerPool init() { - props = new Properties(); - props.put("acks", odeProperties.getProperty("kafka.producer.ack", MessageProducer.DEFAULT_PRODUCER_ACKS)); // Set - // acknowledgments - // for - // producer - // requests. - props.put("retries", - odeProperties.getProperty("kafka.producer.retries", MessageProducer.DEFAULT_PRODUCER_RETRIES)); // If - // the - // request - // fails, - // the - // producer - // can - // automatically retry - props.put("batch.size", - odeProperties.getProperty("kafka.producer.batch.size", MessageProducer.DEFAULT_PRODUCER_BATCH_SIZE_BYTES)); - props.put("linger.ms", - odeProperties.getProperty("kafka.producer.linger.ms", MessageProducer.DEFAULT_PRODUCER_LINGER_MS)); - props.put("buffer.memory", odeProperties.getProperty("kafka.producer.buffer.memory", - MessageProducer.DEFAULT_PRODUCER_BUFFER_MEMORY_BYTES)); - props.put("key.serializer", - odeProperties.getProperty("kafka.key.serializer", MessageProducer.SERIALIZATION_STRING_SERIALIZER)); - props.put("value.serializer", - odeProperties.getProperty("kafka.value.serializer", MessageProducer.SERIALIZATION_BYTE_ARRAY_SERIALIZER)); - props.put("compression.type", odeProperties.getProperty("kafka.producer.compression_type", MessageProducer.COMPRESSION_TYPE)); - - return this; - } - - @Override - protected MessageProducer create() { - return new MessageProducer<>(brokers, type, partitionerClass, props, - odeKafkaProperties.getDisabledTopics()); - } - - @Override - public boolean validate(MessageProducer o) { - return o.getProducer() != null; - } - - @Override - public void expire(MessageProducer o) { - o.close(); - } - - public String getBrokers() { - return brokers; - } - - public void setBrokers(String brokers) { - this.brokers = brokers; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Properties getProps() { - return props; - } - - public void setProps(Properties props) { - this.props = props; - } - - public String getPartitionerClass() { - return partitionerClass; - } +import java.io.Serial; +import java.util.Properties; - public void setPartitionerClass(String partitionerClass) { - this.partitionerClass = partitionerClass; - } +public class SerializableMessageProducerPool extends SerializableObjectPool> { + @Serial + private static final long serialVersionUID = -2293786403623236678L; + + transient OdeKafkaProperties odeKafkaProperties; + + private final String brokers; + private final String type; + private final String partitionerClass; + + private Properties props; + + public SerializableMessageProducerPool(OdeKafkaProperties odeKafkaProperties) { + super(); + this.odeKafkaProperties = odeKafkaProperties; + this.brokers = odeKafkaProperties.getBrokers(); + this.type = odeKafkaProperties.getProducer().getType(); + this.partitionerClass = odeKafkaProperties.getProducer().getPartitionerClass(); + init(); + } + + protected SerializableMessageProducerPool init() { + props = new Properties(); + // Set acknowledgments for producer requests. + props.put("acks", odeKafkaProperties.getProducer().getAcks()); + // If the request fails, the producer can automatically retry + props.put("retries", odeKafkaProperties.getProducer().getRetries()); + props.put("batch.size", odeKafkaProperties.getProducer().getBatchSize()); + props.put("linger.ms", odeKafkaProperties.getProducer().getLingerMs()); + props.put("buffer.memory", odeKafkaProperties.getProducer().getBufferMemory()); + props.put("key.serializer", odeKafkaProperties.getProducer().getKeySerializer()); + props.put("value.serializer", odeKafkaProperties.getProducer().getValueSerializer()); + props.put("kafka.producer.compression_type", odeKafkaProperties.getProducer().getCompressionType()); + + return this; + } + + @Override + protected MessageProducer create() { + return new MessageProducer<>(brokers, type, partitionerClass, props, + odeKafkaProperties.getDisabledTopics()); + } + + @Override + public boolean validate(MessageProducer o) { + return o.getProducer() != null; + } + + @Override + public void expire(MessageProducer o) { + o.close(); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java index b8975125c..9e9ca9e95 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java @@ -26,7 +26,7 @@ public class ByteArrayPublisher implements MessagePublisher { public ByteArrayPublisher(OdeKafkaProperties odeKafkaProperties) { this.bytesProducer = MessageProducer.defaultByteArrayMessageProducer( - odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index c38cbcd22..7852e75e4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -15,8 +15,7 @@ ******************************************************************************/ package us.dot.its.jpo.ode.coder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; import us.dot.its.jpo.ode.kafka.JsonTopics; @@ -26,6 +25,7 @@ import java.io.BufferedInputStream; import java.nio.file.Path; +@Slf4j public class FileAsn1CodecPublisher { public static class FileAsn1CodecPublisherException extends Exception { @@ -38,13 +38,11 @@ public FileAsn1CodecPublisherException(String string, Exception e) { } - private static final Logger logger = LoggerFactory.getLogger(FileAsn1CodecPublisher.class); - private final LogFileToAsn1CodecPublisher codecPublisher; public FileAsn1CodecPublisher(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, RawEncodedJsonTopics rawEncodedJsonTopics) { StringPublisher messagePub = new StringPublisher(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub, jsonTopics, rawEncodedJsonTopics); @@ -54,10 +52,10 @@ public void publishFile(Path filePath, BufferedInputStream fileInputStream, Impo throws FileAsn1CodecPublisherException { String fileName = filePath.toFile().getName(); - logger.info("Publishing file {}", fileName); + log.info("Publishing file {}", fileName); try { - logger.info("Publishing data from {} to asn1_codec.", filePath); + log.info("Publishing data from {} to asn1_codec.", filePath); codecPublisher.publish(fileInputStream, fileName, fileType); } catch (Exception e) { throw new FileAsn1CodecPublisherException("Failed to publish file.", e); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java index ed80e1d27..8e5687075 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeDataPublisher.java @@ -16,8 +16,6 @@ package us.dot.its.jpo.ode.coder; import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeObject; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/CustomConversionServiceConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/CustomConversionServiceConfig.java new file mode 100644 index 000000000..b929cb243 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/CustomConversionServiceConfig.java @@ -0,0 +1,24 @@ +package us.dot.its.jpo.ode.config; + +import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.convert.converter.Converter; +import org.springframework.core.convert.support.DefaultConversionService; + +@Configuration +public class CustomConversionServiceConfig { + + @Bean + @ConfigurationPropertiesBinding + public Converter stringToIntegerConverter() { + return new StringToIntegerConverter(); + } + + @Bean + public DefaultConversionService conversionService() { + DefaultConversionService conversionService = new DefaultConversionService(); + conversionService.addConverter(stringToIntegerConverter()); + return conversionService; + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/StringToIntegerConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/StringToIntegerConverter.java new file mode 100644 index 000000000..5452902c5 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/config/StringToIntegerConverter.java @@ -0,0 +1,18 @@ +package us.dot.its.jpo.ode.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.convert.converter.Converter; + +@Slf4j +public class StringToIntegerConverter implements Converter { + @Override + public Integer convert(String source) { + try { + return Integer.valueOf(source); + } catch (NumberFormatException e) { + // Handle the case where the source is not a valid integer + log.warn("Invalid integer value: {}. The default value will be used instead.", source); + return null; + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java index 0a3081a52..cd79ce198 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java @@ -3,14 +3,31 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; +import us.dot.its.jpo.ode.wrapper.MessageProducer; import java.util.Set; @Configuration @ConfigurationProperties(prefix = "ode.kafka") @Data +@Validated(value = OdeKafkaPropertiesValidator.class) public class OdeKafkaProperties { private String brokers; - private String producerType; private Set disabledTopics; + private Producer producer; + + @Data + public static class Producer { + private Integer batchSize = MessageProducer.DEFAULT_PRODUCER_BATCH_SIZE_BYTES; + private Integer bufferMemory = MessageProducer.DEFAULT_PRODUCER_BUFFER_MEMORY_BYTES; + private Integer lingerMs = MessageProducer.DEFAULT_PRODUCER_LINGER_MS; + private Integer retries = MessageProducer.DEFAULT_PRODUCER_RETRIES; + private String acks = MessageProducer.DEFAULT_PRODUCER_ACKS; + private String keySerializer = MessageProducer.SERIALIZATION_STRING_SERIALIZER; + private String valueSerializer = MessageProducer.SERIALIZATION_BYTE_ARRAY_SERIALIZER; + private String compressionType = MessageProducer.COMPRESSION_TYPE; + private String partitionerClass = "org.apache.kafka.clients.producer.internals.DefaultPartitioner"; + private String type = "sync"; + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java new file mode 100644 index 000000000..da11e5e33 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.kafka; + +import org.springframework.validation.Validator; + +import java.util.List; + +public class OdeKafkaPropertiesValidator implements Validator { + + private static final List VALID_ACKS = List.of("all", "0", "1", "-1"); + + @Override + public boolean supports(Class clazz) { + return OdeKafkaProperties.class.equals(clazz); + } + + @Override + public void validate(Object target, org.springframework.validation.Errors errors) { + OdeKafkaProperties properties = (OdeKafkaProperties) target; + + if (!VALID_ACKS.contains(properties.getProducer().getAcks())) { + errors.rejectValue("producer.acks", "acks value must be one of: " + VALID_ACKS); + } + + if (properties.getBrokers() == null || properties.getBrokers().isEmpty()) { + errors.rejectValue("brokers", "brokers must be set"); + } else { + if (!properties.getBrokers().contains(":")) { + errors.rejectValue("brokers", "broker must be in the format host:port"); + } + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuDepositor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuDepositor.java index 0673189d0..265c704c5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuDepositor.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuDepositor.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2020 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,150 +16,140 @@ package us.dot.its.jpo.ode.rsu; -import java.io.IOException; -import java.text.ParseException; -import java.util.ArrayList; -import java.util.HashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.snmp4j.event.ResponseEvent; - -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.eventlog.EventLogger; -import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.snmp.SnmpSession; import us.dot.its.jpo.ode.traveler.TimTransmogrifier; +import java.io.IOException; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; + +@Slf4j public class RsuDepositor extends Thread { - private Logger logger = LoggerFactory.getLogger(this.getClass()); - private volatile boolean running = true; - private OdeProperties odeProperties; - private ArrayList depositorEntries = new ArrayList(); - - private static boolean dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) - : false; - - class RsuDepositorEntry{ - public RsuDepositorEntry(ServiceRequest request, String encodedMsg) { - this.request = request; - this.encodedMsg = encodedMsg; - } - ServiceRequest request; - String encodedMsg; - } - - public RsuDepositor(OdeProperties odeProperties) { - this.odeProperties = odeProperties; - } - - public OdeProperties getOdeProperties() { - return odeProperties; - } - - public void setOdeProperties(OdeProperties odeProperties) { - this.odeProperties = odeProperties; - } - - public void shutdown() { - running = false; - } - - public boolean isRunning() - { - return running; - } - - public void run() { - try { - while (running) - { - RsuDepositorEntry[] entryList = new RsuDepositorEntry[0]; - synchronized(depositorEntries) - { - entryList = new RsuDepositorEntry[depositorEntries.size()]; - entryList = depositorEntries.toArray(entryList); - depositorEntries.clear(); - } - - for (RsuDepositorEntry entry : entryList) { - HashMap responseList = new HashMap<>(); - for (RSU curRsu : entry.request.getRsus()) { - - TimTransmogrifier.updateRsuCreds(curRsu, odeProperties); - - ResponseEvent rsuResponse = null; - - String httpResponseStatus; - try { - rsuResponse = SnmpSession.createAndSend(entry.request.getSnmp(), curRsu, entry.encodedMsg, entry.request.getOde().getVerb(), dataSigningEnabledRSU); - if (null == rsuResponse || null == rsuResponse.getResponse()) { - // Timeout - httpResponseStatus = "Timeout"; - } else if (rsuResponse.getResponse().getErrorStatus() == 0) { - // Success - httpResponseStatus = "Success"; - } else if (rsuResponse.getResponse().getErrorStatus() == 5) { - // Error, message already exists - httpResponseStatus = "Message already exists at ".concat(Integer.toString(curRsu.getRsuIndex())); - } else if (rsuResponse.getResponse().getErrorStatus() == 10) { - // Error, possible SNMP protocol mismatch - httpResponseStatus = "Possible SNMP protocol mismatch, check RSU configuration"; - } else { - // Misc error - httpResponseStatus = "Error code " + rsuResponse.getResponse().getErrorStatus() + " " - + rsuResponse.getResponse().getErrorStatusText(); - } - } catch (IOException | ParseException e) { - String msg = "Exception caught in TIM RSU deposit loop."; - EventLogger.logger.error(msg, e); - logger.error(msg, e); - httpResponseStatus = e.getClass().getName() + ": " + e.getMessage(); - } - responseList.put(curRsu.getRsuTarget(), httpResponseStatus); - - if (null == rsuResponse || null == rsuResponse.getResponse()) { - // Timeout - logger.error("Error on RSU SNMP deposit to {}: timed out.", curRsu.getRsuTarget()); - } else if (rsuResponse.getResponse().getErrorStatus() == 0) { - // Success - logger.info("RSU SNMP deposit to {} successful.", curRsu.getRsuTarget()); - } else if (rsuResponse.getResponse().getErrorStatus() == 5) { - // Error, message already exists - Integer destIndex = curRsu.getRsuIndex(); - logger.error("Error on RSU SNMP deposit to {}: message already exists at index {}.", curRsu.getRsuTarget(), - destIndex); - } else if (rsuResponse.getResponse().getErrorStatus() == 10) { - // Error, possible SNMP protocol mismatch - logger.error("Error on RSU SNMP deposit to {}: Possible SNMP protocol mismatch, check RSU configuration.", - curRsu.getRsuTarget()); - } else { - // Misc error - logger.error("Error on RSU SNMP deposit to {}: {}", curRsu.getRsuTarget(), "Error code '" - + rsuResponse.getResponse().getErrorStatus() + "' '" + rsuResponse.getResponse().getErrorStatusText() + "'"); - // Log the PDUs involved in the failed deposit - logger.debug("PDUs involved in failed RSU SNMP deposit to " + curRsu.getRsuTarget() - + " => Request PDU: " + rsuResponse.getRequest() + " Response PDU: " + rsuResponse.getResponse()); - } - - } - logger.info("TIM deposit response {}", responseList); - } - Thread.sleep(100); - } - } - catch (InterruptedException e) { - logger.error("RsuDepositor thread interrupted", e); - } - } - - public void deposit(ServiceRequest request, String encodedMsg) { - synchronized(depositorEntries) - { - depositorEntries.add(new RsuDepositorEntry(request, encodedMsg)); - } - } + private final boolean dataSigningEnabled; + private volatile boolean running = true; + private final RsuProperties rsuProperties; + private final ArrayList depositorEntries = new ArrayList<>(); + + protected static class RsuDepositorEntry { + public RsuDepositorEntry(ServiceRequest request, String encodedMsg) { + this.request = request; + this.encodedMsg = encodedMsg; + } + + ServiceRequest request; + String encodedMsg; + } + + public RsuDepositor(RsuProperties rsuProperties, boolean isDataSigningEnabled) { + this.rsuProperties = rsuProperties; + this.dataSigningEnabled = isDataSigningEnabled; + } + + public void shutdown() { + running = false; + } + + public boolean isRunning() { + return running; + } + + @Override + public void run() { + try { + while (running) { + RsuDepositorEntry[] entryList; + synchronized (depositorEntries) { + entryList = new RsuDepositorEntry[depositorEntries.size()]; + entryList = depositorEntries.toArray(entryList); + depositorEntries.clear(); + } + + for (RsuDepositorEntry entry : entryList) { + HashMap responseList = new HashMap<>(); + for (RSU curRsu : entry.request.getRsus()) { + + TimTransmogrifier.updateRsuCreds(curRsu, rsuProperties); + String httpResponseStatus; + try { + ResponseEvent rsuResponse = SnmpSession.createAndSend(entry.request.getSnmp(), + curRsu, + entry.encodedMsg, + entry.request.getOde().getVerb(), + dataSigningEnabled); + httpResponseStatus = getResponseStatus(rsuResponse, curRsu); + } catch (IOException | ParseException e) { + String msg = "Exception caught in TIM RSU deposit loop."; + EventLogger.logger.error(msg, e); + log.error(msg, e); + httpResponseStatus = e.getClass().getName() + ": " + e.getMessage(); + } + + responseList.put(curRsu.getRsuTarget(), httpResponseStatus); + } + log.info("TIM deposit response {}", responseList); + } + Thread.sleep(100); + } + } catch (InterruptedException e) { + log.error("RsuDepositor thread interrupted", e); + } + } + + private String getResponseStatus(ResponseEvent rsuResponse, RSU curRsu) { + String httpResponseStatus; + + if (null == rsuResponse || null == rsuResponse.getResponse()) { + // Timeout + httpResponseStatus = "Timeout"; + log.error("Error on RSU SNMP deposit to {}: timed out.", curRsu.getRsuTarget()); + return httpResponseStatus; + } + + RsuResponseCode responseCode = RsuResponseCode.fromInt(rsuResponse.getResponse().getErrorStatus()); + switch (responseCode) { + case SUCCESS: + httpResponseStatus = "Success"; + log.info("RSU SNMP deposit to {} successful.", curRsu.getRsuTarget()); + break; + case DUPLICATE_MESSAGE: + httpResponseStatus = "Message already exists at ".concat(Integer.toString(curRsu.getRsuIndex())); + Integer destIndex = curRsu.getRsuIndex(); + log.error("Error on RSU SNMP deposit to {}: message already exists at index {}.", curRsu.getRsuTarget(), + destIndex); + break; + case POSSIBLE_SNMP_PROTOCOL_MISMATCH: + httpResponseStatus = "Possible SNMP protocol mismatch, check RSU configuration"; + log.error("Error on RSU SNMP deposit to {}: Possible SNMP protocol mismatch, check RSU configuration.", + curRsu.getRsuTarget()); + break; + case null, default: + httpResponseStatus = "Error code " + rsuResponse.getResponse().getErrorStatus() + " " + + rsuResponse.getResponse().getErrorStatusText(); + // Misc error + log.error("Error on RSU SNMP deposit to {}: Error code '{}' '{}'", curRsu.getRsuTarget(), rsuResponse.getResponse().getErrorStatus(), rsuResponse.getResponse().getErrorStatusText() + "'"); + // Log the PDUs involved in the failed deposit + log.debug("PDUs involved in failed RSU SNMP deposit to {} => Request PDU: {} Response PDU: {}", curRsu.getRsuTarget(), rsuResponse.getRequest(), rsuResponse.getResponse()); + break; + } + + return httpResponseStatus; + } + + public void deposit(ServiceRequest request, String encodedMsg) { + synchronized (depositorEntries) { + depositorEntries.add(new RsuDepositorEntry(request, encodedMsg)); + } + } + protected ArrayList getDepositorEntries() { + synchronized (depositorEntries) { + return depositorEntries; + } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuProperties.java similarity index 93% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuProperties.java index b50640282..3d9c29b9c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RSUProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuProperties.java @@ -4,10 +4,10 @@ import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; -@Data @Configuration @ConfigurationProperties(prefix = "ode.rsu") -public class RSUProperties { +@Data +public class RsuProperties { private int srmSlots; // number of "store and repeat message" indices for RSU TIMs private String username; private String password; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuResponseCode.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuResponseCode.java new file mode 100644 index 000000000..b9bbcdd1a --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/rsu/RsuResponseCode.java @@ -0,0 +1,14 @@ +package us.dot.its.jpo.ode.rsu; + +public enum RsuResponseCode { + SUCCESS, DUPLICATE_MESSAGE, POSSIBLE_SNMP_PROTOCOL_MISMATCH; + + public static RsuResponseCode fromInt(int i) { + return switch (i) { + case 0 -> SUCCESS; + case 5 -> DUPLICATE_MESSAGE; + case 10 -> POSSIBLE_SNMP_PROTOCOL_MISMATCH; + default -> null; + }; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesProperties.java new file mode 100644 index 000000000..a53315ec6 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesProperties.java @@ -0,0 +1,28 @@ +package us.dot.its.jpo.ode.security; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.validation.annotation.Validated; + +@Configuration +@ConfigurationProperties(prefix = "ode.security-services") +@Data +@Validated(value = SecurityServicesPropertiesValidator.class) +public class SecurityServicesProperties { + private String hostIP; + private String signatureEndpoint; + private Integer port = -1; + private Boolean isSdwSigningEnabled = true; + private Boolean isRsuSigningEnabled = false; + + public String getSignatureEndpoint() { + if (signatureEndpoint == null || signatureEndpoint.isEmpty()) { + // if signatureEndpoint is not set, then construct it from hostIP and port + // to provide a useful default. We can't use the default value in the annotation + // because it doesn't allow us to reference other properties. + this.signatureEndpoint = "http://" + hostIP + ":" + port + "/sign"; + } + return signatureEndpoint; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidator.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidator.java new file mode 100644 index 000000000..3b75c7987 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidator.java @@ -0,0 +1,51 @@ +package us.dot.its.jpo.ode.security; + +import org.springframework.validation.Validator; + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Objects; + +public class SecurityServicesPropertiesValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return SecurityServicesProperties.class.equals(clazz); + } + + @Override + public void validate(Object target, org.springframework.validation.Errors errors) { + SecurityServicesProperties properties = (SecurityServicesProperties) target; + + if (Boolean.FALSE.equals(properties.getIsRsuSigningEnabled()) && Boolean.FALSE.equals(properties.getIsSdwSigningEnabled())) { + // if neither RSU nor SDW are enabled, then no further validation is needed because no security services are enabled + return; + } + + if (properties.getSignatureEndpoint() != null && !properties.getSignatureEndpoint().isEmpty()) { + String errorCode = "signatureEndpoint.invalid"; + String fieldName = "signatureEndpoint"; + try { + URI uri = new URI(properties.getSignatureEndpoint()); + if (!uri.getScheme().equals("http") && !uri.getScheme().equals("https")) { + errors.rejectValue(fieldName, errorCode, "Signature endpoint must be an http URL"); + } + if (uri.getHost() == null || Objects.equals(uri.getHost(), "null") || uri.getHost().isEmpty()) { + errors.rejectValue(fieldName, errorCode, "Signature endpoint must have a host"); + } + if (uri.getPort() < 0) { + errors.rejectValue(fieldName, errorCode, "Signature endpoint must have a port"); + } + } catch (URISyntaxException e) { + errors.rejectValue(fieldName, errorCode, "Signature endpoint must be a valid URL"); + } + } else { + if (properties.getHostIP() == null || properties.getHostIP().isEmpty()) { + errors.rejectValue("hostIP", "hostIP.invalid", "Host IP must be provided"); + } + if (properties.getPort() <= 0) { + errors.rejectValue("port", "port.invalid", "Port must be greater than 0"); + } + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index 54781150d..a8bdd7c3f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -23,7 +23,6 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.client.RestTemplate; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; @@ -37,7 +36,9 @@ import us.dot.its.jpo.ode.plugin.SituationDataWarehouse.SDW; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; import us.dot.its.jpo.ode.plugin.j2735.builders.GeoRegionBuilder; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.rsu.RsuDepositor; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.traveler.TimTransmogrifier; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; @@ -75,14 +76,14 @@ public Asn1CommandManagerException(String msg, Exception e) { private String depositTopic; private RsuDepositor rsuDepositor; - public Asn1CommandManager(OdeProperties odeProperties, OdeKafkaProperties odeKafkaProperties, SDXDepositorTopics sdxDepositorTopics) { - this.signatureUri = odeProperties.getSecuritySvcsSignatureUri(); + public Asn1CommandManager(OdeKafkaProperties odeKafkaProperties, SDXDepositorTopics sdxDepositorTopics, RsuProperties rsuProperties, SecurityServicesProperties securityServicesProperties) { + this.signatureUri = securityServicesProperties.getSignatureEndpoint(); try { - this.rsuDepositor = new RsuDepositor(odeProperties); + this.rsuDepositor = new RsuDepositor(rsuProperties, securityServicesProperties.getIsRsuSigningEnabled()); this.rsuDepositor.start(); this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.depositTopic = sdxDepositorTopics.getInput(); } catch (Exception e) { @@ -129,11 +130,11 @@ public String packageSignedTimIntoAsd(ServiceRequest request, String signedMsg) SDW sdw = request.getSdw(); SNMP snmp = request.getSnmp(); - DdsAdvisorySituationData asd = null; + DdsAdvisorySituationData asd; byte sendToRsu = request.getRsus() != null ? DdsAdvisorySituationData.RSU : DdsAdvisorySituationData.NONE; byte distroType = (byte) (DdsAdvisorySituationData.IP | sendToRsu); - // + String outputXml = null; try { if (null != snmp) { @@ -149,7 +150,7 @@ public String packageSignedTimIntoAsd(ServiceRequest request, String signedMsg) .setGroupID(sdw.getGroupID()).setRecordID(sdw.getRecordId()); } - OdeMsgPayload payload = null; + OdeMsgPayload payload; ObjectNode dataBodyObj = JsonUtils.newNode(); ObjectNode asdObj = JsonUtils.toObjectNode(asd.toJson()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index 5461612df..af8809864 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -51,27 +51,27 @@ public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics p this.pojoTopics = pojoTopics; this.jsonTopics = jsonTopics; this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), null, OdeBsmSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 076cf3778..e12831bfe 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -19,7 +19,6 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.OdeTimJsonTopology; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; @@ -29,6 +28,8 @@ import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.plugin.ServiceRequest; +import us.dot.its.jpo.ode.rsu.RsuProperties; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; import us.dot.its.jpo.ode.traveler.TimTransmogrifier; import us.dot.its.jpo.ode.util.CodecUtils; @@ -57,45 +58,38 @@ public Asn1EncodedDataRouterException(String string) { } } - private final OdeProperties odeProperties; private final Asn1CoderTopics asn1CoderTopics; private final JsonTopics jsonTopics; private final MessageProducer stringMsgProducer; private final OdeTimJsonTopology odeTimJsonTopology; private final Asn1CommandManager asn1CommandManager; - private final boolean dataSigningEnabledRSU; private final boolean dataSigningEnabledSDW; + private final boolean dataSigningEnabledRSU; - public Asn1EncodedDataRouter(OdeProperties odeProperties, - OdeKafkaProperties odeKafkaProperties, + public Asn1EncodedDataRouter(OdeKafkaProperties odeKafkaProperties, Asn1CoderTopics asn1CoderTopics, JsonTopics jsonTopics, - SDXDepositorTopics sdxDepositorTopics) { + SDXDepositorTopics sdxDepositorTopics, + RsuProperties rsuProperties, + SecurityServicesProperties securityServicesProperties) { super(); - this.odeProperties = odeProperties; this.asn1CoderTopics = asn1CoderTopics; this.jsonTopics = jsonTopics; this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); - this.asn1CommandManager = new Asn1CommandManager(odeProperties, odeKafkaProperties, sdxDepositorTopics); - - this.dataSigningEnabledRSU = System.getenv("DATA_SIGNING_ENABLED_RSU") != null && !System.getenv("DATA_SIGNING_ENABLED_RSU").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_RSU")) - : false; - this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") != null && !System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() - ? Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")) - : true; + this.asn1CommandManager = new Asn1CommandManager(odeKafkaProperties, sdxDepositorTopics, rsuProperties, securityServicesProperties); + this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); + this.dataSigningEnabledRSU = securityServicesProperties.getIsRsuSigningEnabled(); odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties); if (!odeTimJsonTopology.isRunning()) { odeTimJsonTopology.start(); } - } @Override @@ -213,7 +207,7 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { // Case 1: SNMP-deposit if (dataSigningEnabledRSU && request.getRsus() != null) { - hexEncodedTim = signTIM(hexEncodedTim, consumedObj); + hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); } else { // if header is present, strip it if (isHeaderPresent(hexEncodedTim)) { @@ -238,7 +232,7 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { // Case 2: SDX-deposit if (dataSigningEnabledSDW && request.getSdw() != null) { - hexEncodedTim = signTIM(hexEncodedTim, consumedObj); + hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); } // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated @@ -254,7 +248,6 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { } else { //We have encoded ASD. It could be either UNSECURED or secured. - log.debug("securitySvcsSignatureUri = {}", odeProperties.getSecuritySvcsSignatureUri()); if (dataSigningEnabledSDW && request.getSdw() != null) { log.debug("Signed message received. Depositing it to SDW."); // We have a ASD with signed MessageFrame @@ -344,7 +337,7 @@ public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consum log.info("TIM deposit response {}", responseList); } - public String signTIM(String encodedTIM, JSONObject consumedObj) { + public String signTIMAndProduceToExpireTopic(String encodedTIM, JSONObject consumedObj) { log.debug("Sending message for signature! "); String base64EncodedTim = CodecUtils.toBase64( CodecUtils.fromHex(encodedTIM)); @@ -369,7 +362,7 @@ public String signTIM(String encodedTIM, JSONObject consumedObj) { JSONObject jsonResult = JsonUtils .toJSONObject((JsonUtils.toJSONObject(signedResponse).getString("result"))); // messageExpiry uses unit of seconds - long messageExpiry = Long.valueOf(jsonResult.getString("message-expiry")); + long messageExpiry = Long.parseLong(jsonResult.getString("message-expiry")); timWithExpiration.put("expirationDate", dateFormat.format(new Date(messageExpiry * 1000))); } catch (Exception e) { log.error("Unable to get expiration date from signed messages response ", e); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index c0cceded3..ab8cc3227 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -17,10 +17,14 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.kafka.*; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; +import us.dot.its.jpo.ode.rsu.RsuProperties; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /** @@ -31,12 +35,13 @@ public class AsnCodecRouterServiceController { @Autowired - public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdeProperties") OdeProperties odeProps, - OdeKafkaProperties odeKafkaProperties, + public AsnCodecRouterServiceController(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, PojoTopics pojoTopics, Asn1CoderTopics asn1CoderTopics, - SDXDepositorTopics sdxDepositorTopics) { + SDXDepositorTopics sdxDepositorTopics, + RsuProperties rsuProperties, + SecurityServicesProperties securityServicesProperties) { super(); log.info("Starting {}", this.getClass().getSimpleName()); @@ -55,7 +60,13 @@ public AsnCodecRouterServiceController(@Qualifier("ode-us.dot.its.jpo.ode.OdePro // asn1_codec Encoder Routing log.info("Routing ENCODED data received ASN.1 Encoder"); - Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter(odeProps, odeKafkaProperties, asn1CoderTopics, jsonTopics, sdxDepositorTopics); + Asn1EncodedDataRouter encoderRouter = new Asn1EncodedDataRouter( + odeKafkaProperties, + asn1CoderTopics, + jsonTopics, + sdxDepositorTopics, + rsuProperties, + securityServicesProperties); MessageConsumer encoderConsumer = MessageConsumer.defaultStringMessageConsumer( odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), encoderRouter); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index 43494bf49..5879866e9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeBSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeBSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getBsmStartFlag() ); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java index f28bfd923..919d7bd08 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeMAPJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getMapStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index fd7e225dc..014ce2110 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodePSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodePSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getPsmStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index f6fa8f83f..f48e21524 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeSPATJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSPATJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getSpatStartFlag() ); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 9b9e23a70..0c6c0c5e4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeSRMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSRMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getSrmStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index 215d691dd..1ab2eceef 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeSSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getSsmStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index e4948598e..788c8c6c6 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -20,7 +20,7 @@ public class Asn1DecodeTIMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeTIMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), UperUtil.getTimStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java index 87f314723..ca2a9f42c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java @@ -30,7 +30,7 @@ public class ToJsonConverter extends AbstractSubPubTransformer 0) { - targetob.setAuthoritativeEngineID(authEngineID); - } - - // send request - responseEvent = snmpob.set(pdu, targetob); - if (!keepOpen) { - snmpob.close(); - } - - // if RSU responded and we didn't get an authEngineID, log a warning - if (responseEvent != null && responseEvent.getResponse() != null) { - if (authEngineID == null) { - logger.warn("Failed to discover authoritative engine ID for SNMP target: {}", targetob.getAddress()); + private static final Logger logger = LoggerFactory.getLogger(SnmpSession.class); + + private Snmp snmp; + private TransportMapping transport; + private UserTarget target; + + private boolean ready = false; + private boolean listening; + + /** + * Constructor for SnmpSession + * + * @param props SnmpProperties for the session (target address, retries, + * timeout, etc) + * @throws IOException + */ + public SnmpSession(RSU rsu) throws IOException { + Address addr = GenericAddress.parse(rsu.getRsuTarget() + "/161"); + + // Create a "target" to which a request is sent + target = new UserTarget(); + target.setAddress(addr); + target.setRetries(rsu.getRsuRetries()); + target.setTimeout(rsu.getRsuTimeout()); + target.setVersion(SnmpConstants.version3); + if (rsu.getRsuUsername() != null) { + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); + target.setSecurityName(new OctetString(rsu.getRsuUsername())); + } else { + target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); + } + + // Set up the UDP transport mapping over which requests are sent + transport = null; + try { + transport = new DefaultUdpTransportMapping(); + } catch (IOException e) { + throw new IOException("Failed to create UDP transport mapping: {}", e); + } + + // Instantiate the SNMP instance + snmp = new Snmp(transport); + + // Register the security options and create an SNMP "user" + USM usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0); + SecurityModels.getInstance().addSecurityModel(usm); + if (rsu.getRsuUsername() != null) { + snmp.getUSM().addUser(new OctetString(rsu.getRsuUsername()), new UsmUser(new OctetString(rsu.getRsuUsername()), + AuthSHA.ID, new OctetString(rsu.getRsuPassword()), PrivAES128.ID, new OctetString(rsu.getRsuPassword()))); + } + + // Assert the ready flag so the user can begin sending messages + ready = true; + } + + /** + * Sends a SET-type PDU to the target specified by the constructor. + * + * @param pdu The message content to be sent to the target + * @return ResponseEvent + * @throws IOException + */ + public ResponseEvent set(PDU pdu, Snmp snmpob, UserTarget targetob, Boolean keepOpen) throws IOException { + + // Ensure the object has been instantiated + if (!ready) { + throw new IOException("Tried to send PDU before SNMP sending service is ready."); + } + + if (!listening) { + startListen(); + } + + // Try to send the SNMP request (synchronously) + ResponseEvent
responseEvent; + try { + // attempt to discover & set authoritative engine ID + byte[] authEngineID = snmpob.discoverAuthoritativeEngineID(targetob.getAddress(), 1000); + if (authEngineID != null && authEngineID.length > 0) { + targetob.setAuthoritativeEngineID(authEngineID); + } + + // send request + responseEvent = snmpob.set(pdu, targetob); + if (!keepOpen) { + snmpob.close(); + } + + // if RSU responded and we didn't get an authEngineID, log a warning + if (responseEvent != null && responseEvent.getResponse() != null && authEngineID == null) { + logger.warn("Failed to discover authoritative engine ID for SNMP target: {}", targetob.getAddress()); + } + } catch (IOException e) { + throw new IOException("Failed to send SNMP request: " + e); + } + + return responseEvent; + } + + /** + * Sends a SET-type PDU to the target specified by the constructor. + * + * @param pdu The message content to be sent to the target + * @return ResponseEvent + * @throws IOException + */ + public ResponseEvent get(PDU pdu, Snmp snmpob, UserTarget targetob, Boolean keepOpen) throws IOException { + + // Ensure the object has been instantiated + if (!ready) { + throw new IOException("Tried to send PDU before SNMP sending service is ready."); + } + + // Start listening on UDP + if (!listening) { + startListen(); + } + + // Try to send the SNMP request (synchronously) + ResponseEvent responseEvent = null; + try { + responseEvent = snmpob.get(pdu, targetob); + if (!keepOpen) { + snmpob.close(); } - } - } catch (IOException e) { - throw new IOException("Failed to send SNMP request: " + e); - } - - return responseEvent; - } - - /** - * Sends a SET-type PDU to the target specified by the constructor. - * - * @param pdu The message content to be sent to the target - * @return ResponseEvent - * @throws IOException - */ - public ResponseEvent get(PDU pdu, Snmp snmpob, UserTarget targetob, Boolean keepOpen) throws IOException { - - // Ensure the object has been instantiated - if (!ready) { - throw new IOException("Tried to send PDU before SNMP sending service is ready."); - } - - // Start listening on UDP - if (!listening) { - startListen(); - } - - // Try to send the SNMP request (synchronously) - ResponseEvent responseEvent = null; - try { - responseEvent = snmpob.get(pdu, targetob); - if (!keepOpen) { - snmpob.close(); - } - } catch (IOException e) { - throw new IOException("Failed to send SNMP request: " + e); - } - - return responseEvent; - } - - /** - * Start listening for responses - * - * @throws IOException - */ - public void startListen() throws IOException { - transport.listen(); - listening = true; - } - - /** - * Create an SNMP session given the values in - * - * @param tim - The TIM parameters (payload, channel, mode, etc) - * @param props - The SNMP properties (ip, username, password, etc) - * @return ResponseEvent - * @throws TimPduCreatorException - * @throws IOException - * @throws ParseException - */ - public static ResponseEvent createAndSend(SNMP snmp, RSU rsu, String payload, RequestVerb requestVerb, boolean dataSigningEnabledRSU) - throws ParseException, IOException { - - SnmpSession session = new SnmpSession(rsu); - - // Send the PDU - ResponseEvent response = null; - ScopedPDU pdu = SnmpSession.createPDU(snmp, payload, rsu.getRsuIndex(), requestVerb, rsu.getSnmpProtocol(), dataSigningEnabledRSU); - response = session.set(pdu, session.getSnmp(), session.getTarget(), false); - String msg = "Message Sent to {}, index {}: {}"; - EventLogger.logger.debug(msg, rsu.getRsuTarget(), rsu.getRsuIndex(), payload); - logger.debug(msg, rsu.getRsuTarget(), rsu.getRsuIndex(), payload); - return response; - } - - public Snmp getSnmp() { - return snmp; - } - - public void setSnmp(Snmp snmp) { - this.snmp = snmp; - } - - public TransportMapping getTransport() { - return transport; - } - - public void setTransport(TransportMapping transport) { - this.transport = transport; - } - - public UserTarget getTarget() { - return target; - } - - public void setTarget(UserTarget target) { - this.target = target; - } - - public void endSession() throws IOException { - this.snmp.close(); - } - - /** - * Assembles the various RSU elements of a TimParameters object into a usable - * PDU. - * - * @param index Storage index on the RSU - * @param params TimParameters POJO that stores status, channel, payload, etc. - * @return PDU - * @throws ParseException - */ - public static ScopedPDU createPDU(SNMP snmp, String payload, int index, RequestVerb verb, SnmpProtocol snmpProtocol, boolean dataSigningEnabledRSU) throws ParseException { - switch (snmpProtocol) { - case FOURDOT1: - return createPDUWithFourDot1Protocol(snmp, payload, index, verb); - case NTCIP1218: - return createPDUWithNTCIP1218Protocol(snmp, payload, index, verb, dataSigningEnabledRSU); - default: - logger.error("Unknown SNMP protocol: {}", snmpProtocol); - return null; - } - } - - public static VariableBinding getPEncodedVariableBinding(String oid, String val) { - Integer intVal = Integer.parseInt(val, 16); - Integer additionValue = null; - - if (intVal >= 0 && intVal <= 127) { - // P = V - // here we must instantiate the OctetString directly with the hex string to - // avoid inadvertently creating the ASCII character codes - // for instance OctetString.fromString("20", 16) produces the space character (" - // ") rather than hex 20 - return new VariableBinding(new OID(oid), new OctetString(Integer.toHexString(intVal))); - } else if (intVal >= 128 && intVal <= 16511) { - // P = V + 0x7F80 - additionValue = 0x7F80; - } else if (intVal >= 016512 && intVal <= 2113663) { - // P = V + 0xBFBF80 - additionValue = 0xBFBF80; - } else if (intVal >= 2113664 && intVal <= 270549119) { - // P = V + 0xDFDFBF80 - additionValue = 0xDFDFBF80; - } - - if (additionValue != null) { - return new VariableBinding(new OID(oid), - OctetString.fromString(Integer.toHexString(intVal + additionValue), 16)); - } - return null; - } - - private static ScopedPDU createPDUWithFourDot1Protocol(SNMP snmp, String payload, int index, RequestVerb verb) throws ParseException { - ////////////////////////////// - // - OID examples - // - ////////////////////////////// - // rsuSRMStatus.3 = 4 - // --> 1.4.1.11.3 = 4 - // rsuSRMTxChannel.3 = 3 - // --> 1.4.1.5.3 = 178 - // rsuSRMTxMode.3 = 1 - // --> 1.4.1.4.3 = 1 - // rsuSRMPsid.3 x "8003" - // --> 1.4.1.2.3 x "8003" - // rsuSRMDsrcMsgId.3 = 31 - // --> 1.4.1.3.3 = 31 - // rsuSRMTxInterval.3 = 10 - // --> 1.4.1.6.3 = 10 - // rsuSRMDeliveryStart.3 x "07e7051f0c000000" - // --> 1.4.1.7.3 = "07e7051f0c000000" - // rsuSRMDeliveryStop.3 x "07e7060f0c000000" - // --> 1.4.1.8.3 = "07e7060f0c000000" - // rsuSRMPayload.3 x "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" - // --> 1.4.1.9.3 = "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" - // rsuSRMEnable.3 = 1 - // --> 1.4.1.10.3 = 1 - ////////////////////////////// - - VariableBinding rsuSRMPsid = SnmpFourDot1Protocol.getVbRsuSrmPsid(index, snmp.getRsuid()); - VariableBinding rsuSRMDsrcMsgId = SnmpFourDot1Protocol.getVbRsuSrmDsrcMsgId(index, snmp.getMsgid()); - VariableBinding rsuSRMTxMode = SnmpFourDot1Protocol.getVbRsuSrmTxMode(index, snmp.getMode()); - VariableBinding rsuSRMTxChannel = SnmpFourDot1Protocol.getVbRsuSrmTxChannel(index, snmp.getChannel()); - VariableBinding rsuSRMTxInterval = SnmpFourDot1Protocol.getVbRsuSrmTxInterval(index, snmp.getInterval()); - VariableBinding rsuSRMDeliveryStart = SnmpFourDot1Protocol.getVbRsuSrmDeliveryStart(index, snmp.getDeliverystart()); - VariableBinding rsuSRMDeliveryStop = SnmpFourDot1Protocol.getVbRsuSrmDeliveryStop(index, snmp.getDeliverystop()); - VariableBinding rsuSRMPayload = SnmpFourDot1Protocol.getVbRsuSrmPayload(index, payload); - VariableBinding rsuSRMEnable = SnmpFourDot1Protocol.getVbRsuSrmEnable(index, snmp.getEnable()); - VariableBinding rsuSRMStatus = SnmpFourDot1Protocol.getVbRsuSrmStatus(index, snmp.getStatus()); - - ScopedPDU pdu = new ScopedPDU(); - pdu.add(rsuSRMPsid); - pdu.add(rsuSRMDsrcMsgId); - pdu.add(rsuSRMTxMode); - pdu.add(rsuSRMTxChannel); - pdu.add(rsuSRMTxInterval); - pdu.add(rsuSRMDeliveryStart); - pdu.add(rsuSRMDeliveryStop); - pdu.add(rsuSRMPayload); - pdu.add(rsuSRMEnable); - if (verb == ServiceRequest.OdeInternal.RequestVerb.POST) { + } catch (IOException e) { + throw new IOException("Failed to send SNMP request: " + e); + } + + return responseEvent; + } + + /** + * Start listening for responses + * + * @throws IOException + */ + public void startListen() throws IOException { + transport.listen(); + listening = true; + } + + /** + * Create an SNMP session given the values in + * + * @param tim - The TIM parameters (payload, channel, mode, etc) + * @param props - The SNMP properties (ip, username, password, etc) + * @return ResponseEvent + * @throws TimPduCreatorException + * @throws IOException + * @throws ParseException + */ + public static ResponseEvent createAndSend(SNMP snmp, RSU rsu, String payload, RequestVerb requestVerb, boolean dataSigningEnabledRSU) + throws ParseException, IOException { + + SnmpSession session = new SnmpSession(rsu); + + // Send the PDU + ResponseEvent response = null; + ScopedPDU pdu = SnmpSession.createPDU(snmp, payload, rsu.getRsuIndex(), requestVerb, rsu.getSnmpProtocol(), dataSigningEnabledRSU); + response = session.set(pdu, session.getSnmp(), session.getTarget(), false); + String msg = "Message Sent to {}, index {}: {}"; + EventLogger.logger.debug(msg, rsu.getRsuTarget(), rsu.getRsuIndex(), payload); + logger.debug(msg, rsu.getRsuTarget(), rsu.getRsuIndex(), payload); + return response; + } + + public Snmp getSnmp() { + return snmp; + } + + public void setSnmp(Snmp snmp) { + this.snmp = snmp; + } + + public TransportMapping getTransport() { + return transport; + } + + public void setTransport(TransportMapping transport) { + this.transport = transport; + } + + public UserTarget getTarget() { + return target; + } + + public void setTarget(UserTarget target) { + this.target = target; + } + + public void endSession() throws IOException { + this.snmp.close(); + } + + /** + * Assembles the various RSU elements of a TimParameters object into a usable + * PDU. + * + * @param index Storage index on the RSU + * @param params TimParameters POJO that stores status, channel, payload, etc. + * @return PDU + * @throws ParseException + */ + public static ScopedPDU createPDU(SNMP snmp, String payload, int index, RequestVerb verb, SnmpProtocol snmpProtocol, boolean dataSigningEnabledRSU) throws ParseException { + switch (snmpProtocol) { + case FOURDOT1: + return createPDUWithFourDot1Protocol(snmp, payload, index, verb); + case NTCIP1218: + return createPDUWithNTCIP1218Protocol(snmp, payload, index, verb, dataSigningEnabledRSU); + default: + logger.error("Unknown SNMP protocol: {}", snmpProtocol); + return null; + } + } + + public static VariableBinding getPEncodedVariableBinding(String oid, String val) { + Integer intVal = Integer.parseInt(val, 16); + Integer additionValue = null; + + if (intVal >= 0 && intVal <= 127) { + // P = V + // here we must instantiate the OctetString directly with the hex string to + // avoid inadvertently creating the ASCII character codes + // for instance OctetString.fromString("20", 16) produces the space character (" + // ") rather than hex 20 + return new VariableBinding(new OID(oid), new OctetString(Integer.toHexString(intVal))); + } else if (intVal >= 128 && intVal <= 16511) { + // P = V + 0x7F80 + additionValue = 0x7F80; + } else if (intVal >= 016512 && intVal <= 2113663) { + // P = V + 0xBFBF80 + additionValue = 0xBFBF80; + } else if (intVal >= 2113664 && intVal <= 270549119) { + // P = V + 0xDFDFBF80 + additionValue = 0xDFDFBF80; + } + + if (additionValue != null) { + return new VariableBinding(new OID(oid), + OctetString.fromString(Integer.toHexString(intVal + additionValue), 16)); + } + return null; + } + + private static ScopedPDU createPDUWithFourDot1Protocol(SNMP snmp, String payload, int index, RequestVerb verb) throws ParseException { + ////////////////////////////// + // - OID examples - // + ////////////////////////////// + // rsuSRMStatus.3 = 4 + // --> 1.4.1.11.3 = 4 + // rsuSRMTxChannel.3 = 3 + // --> 1.4.1.5.3 = 178 + // rsuSRMTxMode.3 = 1 + // --> 1.4.1.4.3 = 1 + // rsuSRMPsid.3 x "8003" + // --> 1.4.1.2.3 x "8003" + // rsuSRMDsrcMsgId.3 = 31 + // --> 1.4.1.3.3 = 31 + // rsuSRMTxInterval.3 = 10 + // --> 1.4.1.6.3 = 10 + // rsuSRMDeliveryStart.3 x "07e7051f0c000000" + // --> 1.4.1.7.3 = "07e7051f0c000000" + // rsuSRMDeliveryStop.3 x "07e7060f0c000000" + // --> 1.4.1.8.3 = "07e7060f0c000000" + // rsuSRMPayload.3 x "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" + // --> 1.4.1.9.3 = "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" + // rsuSRMEnable.3 = 1 + // --> 1.4.1.10.3 = 1 + ////////////////////////////// + + VariableBinding rsuSRMPsid = SnmpFourDot1Protocol.getVbRsuSrmPsid(index, snmp.getRsuid()); + VariableBinding rsuSRMDsrcMsgId = SnmpFourDot1Protocol.getVbRsuSrmDsrcMsgId(index, snmp.getMsgid()); + VariableBinding rsuSRMTxMode = SnmpFourDot1Protocol.getVbRsuSrmTxMode(index, snmp.getMode()); + VariableBinding rsuSRMTxChannel = SnmpFourDot1Protocol.getVbRsuSrmTxChannel(index, snmp.getChannel()); + VariableBinding rsuSRMTxInterval = SnmpFourDot1Protocol.getVbRsuSrmTxInterval(index, snmp.getInterval()); + VariableBinding rsuSRMDeliveryStart = SnmpFourDot1Protocol.getVbRsuSrmDeliveryStart(index, snmp.getDeliverystart()); + VariableBinding rsuSRMDeliveryStop = SnmpFourDot1Protocol.getVbRsuSrmDeliveryStop(index, snmp.getDeliverystop()); + VariableBinding rsuSRMPayload = SnmpFourDot1Protocol.getVbRsuSrmPayload(index, payload); + VariableBinding rsuSRMEnable = SnmpFourDot1Protocol.getVbRsuSrmEnable(index, snmp.getEnable()); + VariableBinding rsuSRMStatus = SnmpFourDot1Protocol.getVbRsuSrmStatus(index, snmp.getStatus()); + + ScopedPDU pdu = new ScopedPDU(); + pdu.add(rsuSRMPsid); + pdu.add(rsuSRMDsrcMsgId); + pdu.add(rsuSRMTxMode); + pdu.add(rsuSRMTxChannel); + pdu.add(rsuSRMTxInterval); + pdu.add(rsuSRMDeliveryStart); + pdu.add(rsuSRMDeliveryStop); + pdu.add(rsuSRMPayload); + pdu.add(rsuSRMEnable); + if (verb == ServiceRequest.OdeInternal.RequestVerb.POST) { pdu.add(rsuSRMStatus); - } - pdu.setType(PDU.SET); - - return pdu; - } - - private static ScopedPDU createPDUWithNTCIP1218Protocol(SNMP snmp, String payload, int index, RequestVerb verb, boolean dataSigningEnabledRSU) throws ParseException { - ////////////////////////////// - // - OID examples - // - ////////////////////////////// - // rsuMsgRepeatPsid.3 x "8003" - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 x "8003" - // rsuMsgRepeatTxChannel.3 = 3 - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 183 - // rsuMsgRepeatTxInterval.3 = 10 - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 10 - // rsuMsgRepeatDeliveryStart.3 x "07e7051f0c000000" - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = "07e7051f0c000000" - // rsuMsgRepeatDeliveryStop.3 x "07e7060f0c000000" - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = "07e7060f0c000000" - // rsuMsgRepeatPayload.3 x "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" - // rsuMsgRepeatEnable.3 = 1 - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 1 - // rsuMsgRepeatStatus.3 = 4 - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.9.3 = 4 - // rsuMsgRepeatPriority.3 = 6 - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6 - // rsuMsgRepeatOptions.3 = "00" - // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = "00" - ////////////////////////////// - - VariableBinding rsuMsgRepeatPsid = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPsid(index, snmp.getRsuid()); - // note: dsrc_msg_id is not in NTCIP 1218 - // note: tx_mode is not in NTCIP 1218 - VariableBinding rsuMsgRepeatTxChannel = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatTxChannel(index, snmp.getChannel()); - VariableBinding rsuMsgRepeatTxInterval = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatTxInterval(index, snmp.getInterval()); - VariableBinding rsuMsgRepeatDeliveryStart = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatDeliveryStart(index, snmp.getDeliverystart()); - VariableBinding rsuMsgRepeatDeliveryStop = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatDeliveryStop(index, snmp.getDeliverystop()); - VariableBinding rsuMsgRepeatPayload = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPayload(index, payload); - VariableBinding rsuMsgRepeatEnable = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatEnable(index, snmp.getEnable()); - VariableBinding rsuMsgRepeatStatus = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(index, snmp.getStatus()); - VariableBinding rsuMsgRepeatPriority = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPriority(index); - VariableBinding rsuMsgRepeatOptions; - if (dataSigningEnabledRSU) { + } + pdu.setType(PDU.SET); + + return pdu; + } + + private static ScopedPDU createPDUWithNTCIP1218Protocol(SNMP snmp, String payload, int index, RequestVerb verb, boolean dataSigningEnabledRSU) throws ParseException { + ////////////////////////////// + // - OID examples - // + ////////////////////////////// + // rsuMsgRepeatPsid.3 x "8003" + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.2.3 x "8003" + // rsuMsgRepeatTxChannel.3 = 3 + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.3.3 = 183 + // rsuMsgRepeatTxInterval.3 = 10 + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.4.3 = 10 + // rsuMsgRepeatDeliveryStart.3 x "07e7051f0c000000" + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.5.3 = "07e7051f0c000000" + // rsuMsgRepeatDeliveryStop.3 x "07e7060f0c000000" + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.6.3 = "07e7060f0c000000" + // rsuMsgRepeatPayload.3 x "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.7.3 = "001f6020100000000000de8f834082729de80d80734d37862d2187864fc2099f1f4028407e53bd01b00e69a6f0c5a409c46c3c300118e69a26fa77a0104b8e69a2e86779e21981414e39a68fd29de697d804fb38e69a50e27796151013d81080020290" + // rsuMsgRepeatEnable.3 = 1 + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.8.3 = 1 + // rsuMsgRepeatStatus.3 = 4 + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.9.3 = 4 + // rsuMsgRepeatPriority.3 = 6 + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.10.3 = 6 + // rsuMsgRepeatOptions.3 = "00" + // --> 1.3.6.1.4.1.1206.4.2.18.3.2.1.11.3 = "00" + ////////////////////////////// + + VariableBinding rsuMsgRepeatPsid = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPsid(index, snmp.getRsuid()); + // note: dsrc_msg_id is not in NTCIP 1218 + // note: tx_mode is not in NTCIP 1218 + VariableBinding rsuMsgRepeatTxChannel = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatTxChannel(index, snmp.getChannel()); + VariableBinding rsuMsgRepeatTxInterval = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatTxInterval(index, snmp.getInterval()); + VariableBinding rsuMsgRepeatDeliveryStart = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatDeliveryStart(index, snmp.getDeliverystart()); + VariableBinding rsuMsgRepeatDeliveryStop = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatDeliveryStop(index, snmp.getDeliverystop()); + VariableBinding rsuMsgRepeatPayload = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPayload(index, payload); + VariableBinding rsuMsgRepeatEnable = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatEnable(index, snmp.getEnable()); + VariableBinding rsuMsgRepeatStatus = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(index, snmp.getStatus()); + VariableBinding rsuMsgRepeatPriority = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatPriority(index); + VariableBinding rsuMsgRepeatOptions; + if (dataSigningEnabledRSU) { // set options to 0x00 to tell RSU to broadcast message without signing or attaching a 1609.2 header rsuMsgRepeatOptions = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatOptions(index, 0x00); - } else { + } else { // set options to 0x80 to tell RSU to sign & attach a 1609.2 header before broadcasting rsuMsgRepeatOptions = SnmpNTCIP1218Protocol.getVbRsuMsgRepeatOptions(index, 0x80); - } - - ScopedPDU pdu = new ScopedPDU(); - pdu.add(rsuMsgRepeatPsid); - pdu.add(rsuMsgRepeatTxChannel); - pdu.add(rsuMsgRepeatTxInterval); - pdu.add(rsuMsgRepeatDeliveryStart); - pdu.add(rsuMsgRepeatDeliveryStop); - pdu.add(rsuMsgRepeatPayload); - pdu.add(rsuMsgRepeatEnable); - if (verb == ServiceRequest.OdeInternal.RequestVerb.POST) { + } + + ScopedPDU pdu = new ScopedPDU(); + pdu.add(rsuMsgRepeatPsid); + pdu.add(rsuMsgRepeatTxChannel); + pdu.add(rsuMsgRepeatTxInterval); + pdu.add(rsuMsgRepeatDeliveryStart); + pdu.add(rsuMsgRepeatDeliveryStop); + pdu.add(rsuMsgRepeatPayload); + pdu.add(rsuMsgRepeatEnable); + if (verb == ServiceRequest.OdeInternal.RequestVerb.POST) { pdu.add(rsuMsgRepeatStatus); - } - pdu.add(rsuMsgRepeatPriority); - pdu.add(rsuMsgRepeatOptions); - pdu.setType(PDU.SET); + } + pdu.add(rsuMsgRepeatPriority); + pdu.add(rsuMsgRepeatOptions); + pdu.setType(PDU.SET); - return pdu; - } + return pdu; + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java index 78e6d41fc..e4ec8d473 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/storage/FileSystemStorageService.java @@ -15,28 +15,24 @@ ******************************************************************************/ package us.dot.its.jpo.ode.storage; -import java.io.IOException; -import java.net.MalformedURLException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.stream.Stream; - import lombok.extern.slf4j.Slf4j; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.core.io.Resource; import org.springframework.core.io.UrlResource; import org.springframework.stereotype.Service; import org.springframework.util.FileSystemUtils; import org.springframework.web.multipart.MultipartFile; - -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.eventlog.EventLogger; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.stream.Stream; + @Service @Slf4j public class FileSystemStorageService implements StorageService { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDeleteController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDeleteController.java index 51445a37d..a5e1a12e8 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDeleteController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDeleteController.java @@ -22,9 +22,6 @@ import org.snmp4j.PDU; import org.snmp4j.ScopedPDU; import org.snmp4j.event.ResponseEvent; -import org.snmp4j.smi.Integer32; -import org.snmp4j.smi.OID; -import org.snmp4j.smi.VariableBinding; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -34,9 +31,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.plugin.SnmpProtocol; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.snmp.SnmpFourDot1Protocol; import us.dot.its.jpo.ode.snmp.SnmpNTCIP1218Protocol; import us.dot.its.jpo.ode.snmp.SnmpSession; @@ -49,12 +46,12 @@ public class TimDeleteController { private static final String ERRSTR = "error"; - private OdeProperties odeProperties; + private RsuProperties rsuProperties; @Autowired - public TimDeleteController(OdeProperties odeProperties) { + public TimDeleteController(RsuProperties rsuProperties) { super(); - this.odeProperties = odeProperties; + this.rsuProperties = rsuProperties; } @CrossOrigin @@ -68,7 +65,7 @@ public ResponseEntity deleteTim(@RequestBody String jsonString, } RSU queryTarget = (RSU) JsonUtils.fromJson(jsonString, RSU.class); - TimTransmogrifier.updateRsuCreds(queryTarget, odeProperties); + TimTransmogrifier.updateRsuCreds(queryTarget, rsuProperties); logger.info("TIM delete call, RSU info {}", queryTarget); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index fa7fbc175..5062017cc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -36,6 +36,7 @@ import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame; import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.traveler.TimTransmogrifier.TimTransmogrifierException; import us.dot.its.jpo.ode.util.DateTimeUtils; import us.dot.its.jpo.ode.util.JsonUtils; @@ -85,7 +86,12 @@ public TimDepositControllerException(String errMsg) { } @Autowired - public TimDepositController(OdeKafkaProperties odeKafkaProperties, Asn1CoderTopics asn1CoderTopics, PojoTopics pojoTopics, JsonTopics jsonTopics, TimIngestTrackerProperties ingestTrackerProperties) { + public TimDepositController(OdeKafkaProperties odeKafkaProperties, + Asn1CoderTopics asn1CoderTopics, + PojoTopics pojoTopics, + JsonTopics jsonTopics, + TimIngestTrackerProperties ingestTrackerProperties, + SecurityServicesProperties securityServicesProperties) { super(); this.asn1CoderTopics = asn1CoderTopics; @@ -95,11 +101,11 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, Asn1CoderTopi this.serialIdOde = new SerialId(); this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); - this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); - this.dataSigningEnabledSDW = System.getenv("DATA_SIGNING_ENABLED_SDW") == null || System.getenv("DATA_SIGNING_ENABLED_SDW").isEmpty() || Boolean.parseBoolean(System.getenv("DATA_SIGNING_ENABLED_SDW")); + this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); // start the TIM ingest monitoring service if enabled if (ingestTrackerProperties.isTrackingEnabled()) { @@ -132,7 +138,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - OdeTravelerInputData odeTID = null; + OdeTravelerInputData odeTID; ServiceRequest request; try { // Convert JSON to POJO @@ -178,15 +184,14 @@ public synchronized ResponseEntity depositTim(String jsonString, Request int maxDurationTime = 0; Date latestStartDateTime = null; for (DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = maxDurationTime > dataFrameItem.getDurationTime() ? maxDurationTime - : dataFrameItem.getDurationTime(); + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); try { latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) ? dateFormat.parse(dataFrameItem.getStartDateTime()) : latestStartDateTime); } catch (ParseException e) { - log.error("Invalid dateTime parse: " + e); + log.error("Invalid dateTime parse: ", e); } } timMetadata.setMaxDurationTime(maxDurationTime); @@ -200,7 +205,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request try { timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); - } catch (ParseException | DateTimeParseException e) { + } catch (DateTimeParseException e) { String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); @@ -212,7 +217,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); - // Now that the message gas been published to OdeBradcastTim topic, it should be + // Now that the message has been published to OdeBroadcastTim topic, it should be // changed to J2735BroadcastTim serialId timMetadata.setSerialId(serialIdJ2735); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java index 2104d6a73..712e576a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimQueryController.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -15,15 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import java.io.IOException; -import java.util.HashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import lombok.extern.slf4j.Slf4j; import org.snmp4j.PDU; import org.snmp4j.ScopedPDU; import org.snmp4j.event.ResponseEvent; -import org.snmp4j.smi.OID; import org.snmp4j.smi.VariableBinding; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -32,147 +27,147 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; - -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.plugin.SnmpProtocol; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.plugin.SnmpProtocol; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.snmp.SnmpFourDot1Protocol; import us.dot.its.jpo.ode.snmp.SnmpNTCIP1218Protocol; import us.dot.its.jpo.ode.snmp.SnmpSession; import us.dot.its.jpo.ode.util.JsonUtils; +import java.io.IOException; +import java.util.HashMap; + @RestController +@Slf4j public class TimQueryController { - - private static final Logger logger = LoggerFactory.getLogger(TimQueryController.class); - - private static final String ERRSTR = "error"; - - private OdeProperties odeProperties; - - @Autowired - public TimQueryController(OdeProperties odeProperties) { - this.odeProperties = odeProperties; - } - - /** - * Checks given RSU for all TIMs set - * - * @param jsonString - * Request body containing RSU info - * @return list of occupied TIM slots on RSU - */ - @CrossOrigin - @PostMapping(value = "/tim/query") - public synchronized ResponseEntity bulkQuery(@RequestBody String jsonString) { // NOSONAR - - if (null == jsonString || jsonString.isEmpty()) { - logger.error("Empty request."); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, "Empty request.")); - } - - RSU queryTarget = null; - try { - queryTarget = (RSU) JsonUtils.fromJson(jsonString, RSU.class); - } - catch(Exception e) { - - } - if (queryTarget == null) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, "Unrecognized protocol")); - } - - TimTransmogrifier.updateRsuCreds(queryTarget, odeProperties); - - SnmpSession snmpSession = null; - try { - snmpSession = new SnmpSession(queryTarget); - snmpSession.startListen(); - } catch (IOException e) { - logger.error("Error creating SNMP session.", e); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(JsonUtils.jsonKeyValue(ERRSTR, "Failed to create SNMP session.")); - } - - PDU pdu0 = new ScopedPDU(); - pdu0.setType(PDU.GET); - PDU pdu1 = new ScopedPDU(); - pdu1.setType(PDU.GET); - - SnmpProtocol snmpProtocol = queryTarget.getSnmpProtocol(); - - if (snmpProtocol == null) { - logger.error("No SNMP protocol specified."); - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(JsonUtils.jsonKeyValue(ERRSTR, "No SNMP protocol specified.")); - } - - if (snmpProtocol == SnmpProtocol.FOURDOT1) { - for (int i = 0; i < odeProperties.rsuProperties().getSrmSlots() - 50; i++) { - pdu0.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); - } - - for (int i = 50; i < odeProperties.rsuProperties().getSrmSlots(); i++) { - pdu1.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); - } - } - else if (snmpProtocol == SnmpProtocol.NTCIP1218) { - for (int i = 0; i < odeProperties.rsuProperties().getSrmSlots() - 50; i++) { - pdu0.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); - } - - for (int i = 50; i < odeProperties.rsuProperties().getSrmSlots(); i++) { - pdu1.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); - } - } - else { - logger.error("Unsupported SNMP protocol: {}", snmpProtocol); - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(JsonUtils.jsonKeyValue(ERRSTR, "Unsupported SNMP protocol: " + snmpProtocol)); - } - - ResponseEvent response0 = null; - ResponseEvent response1 = null; - try { - response0 = snmpSession.getSnmp().send(pdu0, snmpSession.getTarget()); - response1 = snmpSession.getSnmp().send(pdu1, snmpSession.getTarget()); - } catch (IOException e) { - logger.error("Error creating SNMP session.", e); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body(JsonUtils.jsonKeyValue(ERRSTR, "Failed to create SNMP session.")); - } - - // Process response - if (response0 == null || response0.getResponse() == null || response1 == null - || response1.getResponse() == null) { - logger.error("RSU query failed, timeout."); - return ResponseEntity.status(HttpStatus.BAD_REQUEST) - .body(JsonUtils.jsonKeyValue(ERRSTR, "Timeout, no response from RSU.")); - } - - HashMap resultsMap = new HashMap<>(); - for (Object vbo : response0.getResponse().getVariableBindings().toArray()) { - VariableBinding vb = (VariableBinding) vbo; - if (vb.getVariable().toInt() == 1) { - resultsMap.put(vb.getOid().toString().substring(21), true); - } - } - - for (Object vbo : response1.getResponse().getVariableBindings().toArray()) { - VariableBinding vb = (VariableBinding) vbo; - if (vb.getVariable().toInt() == 1) { - resultsMap.put(vb.getOid().toString().substring(21), true); - } - } - - try { - snmpSession.endSession(); - } catch (IOException e) { - logger.error("Error closing SNMP session.", e); - } - - logger.info("RSU query successful: {}", resultsMap.keySet()); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue("indicies_set", resultsMap.keySet().toString())); - } - + + private static final String ERRSTR = "error"; + + private final RsuProperties rsuProperties; + + @Autowired + public TimQueryController(RsuProperties rsuProperties) { + this.rsuProperties = rsuProperties; + } + + /** + * Checks given RSU for all TIMs set + * + * @param jsonString Request body containing RSU info + * @return list of occupied TIM slots on RSU + */ + @CrossOrigin + @PostMapping(value = "/tim/query") + public synchronized ResponseEntity bulkQuery(@RequestBody String jsonString) { // NOSONAR + + if (null == jsonString || jsonString.isEmpty()) { + log.error("Empty request."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, "Empty request.")); + } + + RSU queryTarget = null; + try { + queryTarget = (RSU) JsonUtils.fromJson(jsonString, RSU.class); + } catch (Exception e) { + log.error("Convert JSON to RSU failed.", e); + } + if (queryTarget == null) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, "Unrecognized protocol")); + } + + TimTransmogrifier.updateRsuCreds(queryTarget, rsuProperties); + + SnmpSession snmpSession = null; + try { + snmpSession = new SnmpSession(queryTarget); + snmpSession.startListen(); + } catch (IOException e) { + log.error("Error creating SNMP session.", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(JsonUtils.jsonKeyValue(ERRSTR, "Failed to create SNMP session.")); + } + + PDU pdu0 = new ScopedPDU(); + pdu0.setType(PDU.GET); + PDU pdu1 = new ScopedPDU(); + pdu1.setType(PDU.GET); + + SnmpProtocol snmpProtocol = queryTarget.getSnmpProtocol(); + + if (snmpProtocol == null) { + log.error("No SNMP protocol specified."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, "No SNMP protocol specified.")); + } + + switch (snmpProtocol) { + case SnmpProtocol.FOURDOT1 -> { + for (int i = 0; i < rsuProperties.getSrmSlots() - 50; i++) { + pdu0.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); + } + + for (int i = 50; i < rsuProperties.getSrmSlots(); i++) { + pdu1.add(SnmpFourDot1Protocol.getVbRsuSrmStatus(i)); + } + } + case SnmpProtocol.NTCIP1218 -> { + for (int i = 0; i < rsuProperties.getSrmSlots() - 50; i++) { + pdu0.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); + } + + for (int i = 50; i < rsuProperties.getSrmSlots(); i++) { + pdu1.add(SnmpNTCIP1218Protocol.getVbRsuMsgRepeatStatus(i)); + } + } + default -> { + log.error("Unsupported SNMP protocol: {}", snmpProtocol); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, "Unsupported SNMP protocol: " + snmpProtocol)); + } + } + + ResponseEvent response0 = null; + ResponseEvent response1 = null; + try { + response0 = snmpSession.getSnmp().send(pdu0, snmpSession.getTarget()); + response1 = snmpSession.getSnmp().send(pdu1, snmpSession.getTarget()); + } catch (IOException e) { + log.error("Error creating SNMP session.", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(JsonUtils.jsonKeyValue(ERRSTR, "Failed to create SNMP session.")); + } + + // Process response + if (response0 == null || response0.getResponse() == null || response1 == null + || response1.getResponse() == null) { + log.error("RSU query failed, timeout."); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, "Timeout, no response from RSU.")); + } + + HashMap resultsMap = new HashMap<>(); + for (Object vbo : response0.getResponse().getVariableBindings().toArray()) { + VariableBinding vb = (VariableBinding) vbo; + if (vb.getVariable().toInt() == 1) { + resultsMap.put(vb.getOid().toString().substring(21), true); + } + } + + for (Object vbo : response1.getResponse().getVariableBindings().toArray()) { + VariableBinding vb = (VariableBinding) vbo; + if (vb.getVariable().toInt() == 1) { + resultsMap.put(vb.getOid().toString().substring(21), true); + } + } + + try { + snmpSession.endSession(); + } catch (IOException e) { + log.error("Error closing SNMP session.", e); + } + + log.info("RSU query successful: {}", resultsMap.keySet()); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue("indicies_set", resultsMap.keySet().toString())); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java index ea237d21e..5ab4561d0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java @@ -6,7 +6,6 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; @@ -29,6 +28,7 @@ import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; import us.dot.its.jpo.ode.plugin.j2735.timstorage.MessageFrame; import us.dot.its.jpo.ode.plugin.j2735.timstorage.TravelerInputData; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; import us.dot.its.jpo.ode.util.XmlUtils; @@ -220,14 +220,14 @@ private static ArrayNode buildEncodings(DdsAdvisorySituationData asd) throws Jso return encodings; } - public static void updateRsuCreds(RSU rsu, OdeProperties odeProperties) { + public static void updateRsuCreds(RSU rsu, RsuProperties rsuProperties) { if (rsu.getRsuUsername() == null || rsu.getRsuUsername().isEmpty()) { - rsu.setRsuUsername(odeProperties.rsuProperties().getUsername()); + rsu.setRsuUsername(rsuProperties.getUsername()); } if (rsu.getRsuPassword() == null || rsu.getRsuPassword().isEmpty()) { - rsu.setRsuPassword(odeProperties.rsuProperties().getPassword()); + rsu.setRsuPassword(rsuProperties.getPassword()); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java index 595b9663b..59586800a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/AbstractUdpReceiverPublisher.java @@ -1,7 +1,6 @@ package us.dot.its.jpo.ode.udp; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.OdeProperties; import java.net.DatagramSocket; import java.net.SocketException; @@ -22,8 +21,7 @@ public UdpReceiverException(String string, Exception e) { protected String senderIp; protected int senderPort; - protected OdeProperties odeProperties; - protected int port; + protected int port; protected int bufferSize; private boolean stopped = false; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index 43d9b7367..a8d0a6468 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -19,25 +19,21 @@ public BsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - log.debug("BSM UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { log.debug("Waiting for UDP BSM packets..."); this.socket.receive(packet); if (packet.getLength() > 0) { String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - if (bsmJson != null) { bsmPublisher.publish(publishTopic, bsmJson); } @@ -47,6 +43,4 @@ public void run() { } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index 0dc994ef1..c94a27bae 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -21,7 +21,7 @@ public class GenericReceiver extends AbstractUdpReceiverPublisher { public GenericReceiver(UDPReceiverProperties.ReceiverProperties props, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { super(props.getReceiverPort(), props.getBufferSize()); - this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); this.rawEncodedJsonTopics = rawEncodedJsonTopics; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index eed9651ab..45612401f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -18,7 +18,7 @@ public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.mapPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.mapPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override @@ -27,24 +27,19 @@ public void run() { byte[] buffer = new byte[bufferSize]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { log.debug("Waiting for UDP Map packets..."); socket.receive(packet); if (packet.getLength() > 0) { - String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); if (mapJson != null) { mapPublisher.publish(this.publishTopic, mapJson); } - } } catch (Exception e) { log.error("Error receiving packet", e); } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index fe884fc5c..a9c49b829 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -19,7 +19,7 @@ public PsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override @@ -28,7 +28,6 @@ public void run() { byte[] buffer = new byte[bufferSize]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { log.debug("Waiting for UDP PSM packets..."); @@ -44,6 +43,4 @@ public void run() { } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index 5dbc38a5f..d52e739ec 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -19,18 +19,15 @@ public SpatReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - log.debug("SPaT UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { log.debug("Waiting for UDP SPaT packets..."); @@ -46,6 +43,4 @@ public void run() { } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index 71b2f02e7..de24c959e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -1,17 +1,16 @@ package us.dot.its.jpo.ode.udp.srm; -import java.net.DatagramPacket; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.StringPublisher; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import java.net.DatagramPacket; + +@Slf4j public class SrmReceiver extends AbstractUdpReceiverPublisher { - private static Logger logger = LoggerFactory.getLogger(SrmReceiver.class); private final StringPublisher srmPublisher; private final String publishTopic; @@ -20,34 +19,28 @@ public SrmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override public void run() { - - logger.debug("SRM UDP Receiver Service started."); + log.debug("SRM UDP Receiver Service started."); byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { - logger.debug("Waiting for UDP SRM packets..."); + log.debug("Waiting for UDP SRM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); - if(srmJson != null){ + if (srmJson != null) { srmPublisher.publish(publishTopic, srmJson); } } } catch (Exception e) { - logger.error("Error receiving packet", e); + log.error("Error receiving packet", e); } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index 89af94ae5..4f73012c4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -19,7 +19,7 @@ public SsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override @@ -28,25 +28,19 @@ public void run() { byte[] buffer = new byte[bufferSize]; DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { try { log.debug("Waiting for UDP SSM packets..."); socket.receive(packet); if (packet.getLength() > 0) { - String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - if (ssmJson != null) { ssmPublisher.publish(this.publishTopic, ssmJson); } - } } catch (Exception e) { log.error("Error receiving packet", e); } } while (!isStopped()); } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 5d2e43636..1aa457139 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -19,7 +19,7 @@ public TimReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducerType(), odeKafkaProperties.getDisabledTopics()); + this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index b2d87053e..f6418668d 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -4,19 +4,30 @@ spring: max-file-size: 1MB max-request-size: 1MB ode: - host-ip: ${DOCKER_HOST_IP} - verbose-json: false - plugins-locations: "plugins" output-schema-version: 7 - security-svcs-port: 8090 - security-svcs-signature-endpoint: "sign" + security-services: + host-ip: ${DOCKER_HOST_IP} + port: 8090 + signature-endpoint: ${ODE_SECURITY_SVCS_SIGNATURE_URI} + is-rsu-signing-enabled: ${DATA_SIGNING_ENABLED_RSU} + is-sdw-signing-enabled: ${DATA_SIGNING_ENABLED_SDW} rsu: srm-slots: 100 username: ${RSU_USERNAME} password: ${RSU_PASSWORD} kafka: brokers: ${DOCKER_HOST_IP}:9092 - producer-type: sync + producer: + type: "sync" + acks: ${KAFKA_ACKS} + retries: ${KAFKA_RETRIES} + batch-size: ${KAFKA_BATCH_SIZE} + linger-ms: ${KAFKA_LINGER_MS} + buffer-memory: ${KAFKA_BUFFER_MEMORY} + key-serializer: ${KAFKA_KEY_SERIALIZER} + value-serializer: ${KAFKA_VALUE_SERIALIZER} + partitioner-class: ${KAFKA_PARTITIONER_CLASS} + compression-type: ${KAFKA_COMPRESSION_TYPE} disabled-topics: - "topic.OdeBsmRxPojo" - "topic.OdeBsmTxPojo" diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java index 2e8742f03..f87c1c42b 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java @@ -9,15 +9,13 @@ import org.springframework.context.annotation.Import; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.rsu.RSUProperties; import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @Import({BuildProperties.class}) -@EnableConfigurationProperties(value = {OdeProperties.class, RSUProperties.class, org.springframework.boot.info.BuildProperties.class}) +@EnableConfigurationProperties(value = {OdeProperties.class, org.springframework.boot.info.BuildProperties.class}) class OdePropertiesTest { @Autowired @@ -27,45 +25,4 @@ class OdePropertiesTest { void testOutputSchemaVersion() { assertEquals(7, testOdeProperties.getOutputSchemaVersion()); } - - @Test - void testPluginsLocations() { - assertEquals("plugins", testOdeProperties.getPluginsLocations()); - } - - @Test - void testHostIP() { - assertEquals("test-host", testOdeProperties.getHostIP()); - } - - @Test - void testVerboseJson() { - assertFalse(testOdeProperties.isVerboseJson()); - } - - @Test - void testSecuritySvcsSignatureUri() { - String expected = "http://" + testOdeProperties.getHostIP() + ":" + testOdeProperties.getSecuritySvcsPort() + "/" - + testOdeProperties.getSecuritySvcsSignatureEndpoint(); - assertEquals(expected, testOdeProperties.getSecuritySvcsSignatureUri()); - } - - @Test - void testSecuritySvcsPort() { - assertEquals(8090, testOdeProperties.getSecuritySvcsPort()); - } - - @Test - void testSecuritySvcsSignatureEndpoint() { - assertEquals("sign", testOdeProperties.getSecuritySvcsSignatureEndpoint()); - } - - @Test - void testRsuProperties() { - RSUProperties rsuProperties = testOdeProperties.rsuProperties(); - - assertEquals(100, rsuProperties.getSrmSlots()); - assertEquals("test-username", rsuProperties.getUsername()); - assertEquals("test-password", rsuProperties.getPassword()); - } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java index 4a9f76bb1..709cfdc7e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/SerializableMessageProducerPoolTest.java @@ -15,118 +15,52 @@ ******************************************************************************/ package us.dot.its.jpo.ode; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.util.Properties; -import java.util.Set; - import org.apache.kafka.clients.producer.Producer; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; - -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; -import mockit.Verifications; -//import mockit.integration.junit4.JMockit; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.info.BuildProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; -//@RunWith(JMockit.class) -public class SerializableMessageProducerPoolTest { +import static org.junit.jupiter.api.Assertions.*; - @Tested - SerializableMessageProducerPool testSerializableMessageProducerPool; - @Injectable - OdeProperties mockOdeProperties; - @Injectable - OdeKafkaProperties injectableOdeKafkaProperties; +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@Import({BuildProperties.class}) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class}) +class SerializableMessageProducerPoolTest { - @BeforeEach - public void setUp() { - new Expectations() { - { - mockOdeProperties.getProperty(anyString, anyInt); - result = "test1"; - mockOdeProperties.getProperty(anyString, anyString); - result = "test2"; - } - }; - } + @Autowired + OdeKafkaProperties testOdeKafkaProperties; - @SuppressWarnings("unchecked") @Test - public void testCreate(@Mocked final MessageProducer mockMessageProducer) { - new Expectations() { - { - new MessageProducer(anyString, anyString, anyString, - (Properties) any, (Set)any); - } - }; - - assertTrue(testSerializableMessageProducerPool.create() instanceof MessageProducer); + void testCreate() { + SerializableMessageProducerPool testSerializableMessageProducerPool = new SerializableMessageProducerPool<>(testOdeKafkaProperties); + assertEquals(MessageProducer.class, testSerializableMessageProducerPool.create().getClass()); } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Test - public void testValidateTrue(@Injectable MessageProducer mockMessageProducer, @Mocked Producer mockProducer) { - - new Expectations() { - { - mockMessageProducer.getProducer(); - result = mockProducer; - } - }; - - assertTrue(testSerializableMessageProducerPool.validate(mockMessageProducer)); - + void testValidate() { + SerializableMessageProducerPool testSerializableMessageProducerPool = new SerializableMessageProducerPool<>(testOdeKafkaProperties); + MessageProducer producer = testSerializableMessageProducerPool.create(); + assertTrue(testSerializableMessageProducerPool.validate(producer)); } - @SuppressWarnings({ "rawtypes", "unchecked" }) @Test - public void testValidateFalse(@Injectable MessageProducer mockMessageProducer) { - - new Expectations() { - { - mockMessageProducer.getProducer(); - result = null; - } - }; - - assertFalse(testSerializableMessageProducerPool.validate(mockMessageProducer)); - + void testExpire() { + SerializableMessageProducerPool testSerializableMessageProducerPool = new SerializableMessageProducerPool<>(testOdeKafkaProperties); + MessageProducer producer = testSerializableMessageProducerPool.create(); + testSerializableMessageProducerPool.expire(producer); + + // To confirm that the producer has been expired, we will try to send a message. + // If the producer has been expired, it will throw an IllegalStateException. + Producer internalProducer = producer.getProducer(); + assertThrows(IllegalStateException.class, () -> internalProducer.send(null)); } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test - public void testExpire(@Injectable MessageProducer mockMessageProducer) { - testSerializableMessageProducerPool.expire(mockMessageProducer); - - new Verifications() { - { - mockMessageProducer.close(); - } - }; - } - - @Test - public void testSettersAndGetters() { - - testSerializableMessageProducerPool.setBrokers("testBrokers123"); - assertEquals("testBrokers123", testSerializableMessageProducerPool.getBrokers()); - - testSerializableMessageProducerPool.setPartitionerClass("testPartitionerClass123"); - assertEquals("testPartitionerClass123", testSerializableMessageProducerPool.getPartitionerClass()); - - testSerializableMessageProducerPool.setType("testType123"); - assertEquals("testType123", testSerializableMessageProducerPool.getType()); - - testSerializableMessageProducerPool.setProps(null); - assertNull(testSerializableMessageProducerPool.getProps()); - } - } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java index 5c0832a72..8287ccb48 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/ByteArrayPublisherTest.java @@ -23,15 +23,13 @@ import mockit.Mocked; import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageProducer; public class ByteArrayPublisherTest { @Tested ByteArrayPublisher testMessagePublisher; - @Injectable - OdeProperties testOdeProperties; + @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @Injectable diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java index dc6fbf7b4..01f42197f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/exporter/StompStringExporterTest.java @@ -19,7 +19,6 @@ import org.junit.jupiter.api.Test; import org.springframework.messaging.simp.SimpMessagingTemplate; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; @@ -28,8 +27,6 @@ public class StompStringExporterTest { @Tested StompStringExporter testStompExporter; - @Injectable - OdeProperties injectableOdeProperties; @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @Injectable diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterProcessorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterProcessorTest.java index 9e8ff6317..27ccdc779 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterProcessorTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterProcessorTest.java @@ -29,13 +29,10 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; import mockit.Mocked; import mockit.Tested; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; public class ImporterProcessorTest { @@ -43,8 +40,6 @@ public class ImporterProcessorTest { @Tested ImporterProcessor testImporterProcessor; - @Injectable - OdeProperties injectableOdeProperties; @Injectable ImporterFileType injectableImporterDirType = ImporterFileType.LOG_FILE; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java index 1f23358ba..42aaaa951 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java @@ -10,8 +10,7 @@ import java.util.Set; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @@ -26,11 +25,6 @@ void testGetBrokers() { assertEquals("localhost:9092", odeKafkaProperties.getBrokers()); } - @Test - void testGetProducerType() { - assertEquals("sync", odeKafkaProperties.getProducerType()); - } - @Test void testGetKafkaTopicsDisabled() { Set kafkaTopicsDisabled = odeKafkaProperties.getDisabledTopics(); @@ -40,4 +34,54 @@ void testGetKafkaTopicsDisabled() { assertTrue(kafkaTopicsDisabled.contains("topic.OdeBsmDuringEventPojo")); assertTrue(kafkaTopicsDisabled.contains("topic.OdeTimBroadcastPojo")); } + + @Test + void testGetProducerAcks() { + assertEquals("0", odeKafkaProperties.getProducer().getAcks()); + } + + @Test + void testGetProducerBatchSize() { + assertEquals( 1638, odeKafkaProperties.getProducer().getBatchSize()); + } + + @Test + void testGetProducerBufferMemory() { + assertEquals(33554433, odeKafkaProperties.getProducer().getBufferMemory()); + } + + @Test + void testGetProducerKeySerializer() { + assertEquals("org.apache.kafka.common.serialization.StringSerializer", odeKafkaProperties.getProducer().getKeySerializer()); + } + + @Test + void testGetProducerLingerMs() { + assertEquals(2, odeKafkaProperties.getProducer().getLingerMs()); + } + + @Test + void testGetProducerPartitionerClass() { + assertEquals("org.apache.kafka.clients.producer.internals.DefaultPartitioner", odeKafkaProperties.getProducer().getPartitionerClass()); + } + + @Test + void testGetProducerRetries() { + assertEquals(1, odeKafkaProperties.getProducer().getRetries()); + } + + @Test + void testGetProducerType() { + assertEquals("async", odeKafkaProperties.getProducer().getType()); + } + + @Test + void testGetProducerValueSerializer() { + assertEquals("org.apache.kafka.common.serialization.ByteArraySerializer", odeKafkaProperties.getProducer().getValueSerializer()); + } + + @Test + void testGetProducerCompressionType() { + assertEquals("zstd", odeKafkaProperties.getProducer().getCompressionType()); + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java new file mode 100644 index 000000000..09e1bda95 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java @@ -0,0 +1,60 @@ +package us.dot.its.jpo.ode.kafka; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class OdeKafkaPropertiesValidatorTest { + + @Test + void supports() { + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + assertTrue(validator.supports(OdeKafkaProperties.class)); + assertFalse(validator.supports(Object.class)); + } + + @Test + void validate() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers("localhost:9092"); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("all"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertFalse(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidAcks() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers("localhost:9092"); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("none"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidBrokers() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers(""); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("all"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/rsu/RsuDepositorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/rsu/RsuDepositorTest.java index 99f53b7e5..a5451376f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/rsu/RsuDepositorTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/rsu/RsuDepositorTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2020 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,68 +16,46 @@ package us.dot.its.jpo.ode.rsu; -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.text.ParseException; - import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; - -import mockit.Capturing; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; -//import mockit.integration.junit4.JMockit; -import us.dot.its.jpo.ode.OdeProperties; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.model.OdeTravelerInputData; -import us.dot.its.jpo.ode.snmp.SnmpSession; -import us.dot.its.jpo.ode.wrapper.MessageProducer; - -//@RunWith(JMockit.class) -public class RsuDepositorTest { - - @Tested - RsuDepositor testRsuDepositor; - - @Injectable - OdeProperties injectableOdeProperties; - @Capturing - MessageProducer capturingMessageProducer; - @Capturing - SnmpSession capturingSnmpSession; - - @Injectable - OdeTravelerInputData injectableOdeTravelerInputData; - - @Mocked - MessageProducer mockMessageProducer; - @Test - public void shouldConstruct(@Mocked OdeProperties mockOdeProperties) { - testRsuDepositor = new RsuDepositor(mockOdeProperties); - testRsuDepositor.start(); - assertEquals(mockOdeProperties, testRsuDepositor.getOdeProperties()); +import us.dot.its.jpo.ode.security.SecurityServicesProperties; - } +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; - @Test - public void testShutdown() { - testRsuDepositor.shutdown(); - assertEquals(false, testRsuDepositor.isRunning()); - assertEquals(false, testRsuDepositor.isAlive()); +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = {RsuProperties.class, SecurityServicesProperties.class}) +class RsuDepositorTest { - } + @Autowired + RsuProperties rsuProperties; + @Autowired + SecurityServicesProperties securityServicesProperties; - @Test - public void testDeposit(@Mocked OdeTravelerInputData mockOdeTravelerInputData) - throws IOException, ParseException { - - testRsuDepositor.deposit(mockOdeTravelerInputData.getRequest(), "message"); - - } + @Test + void testShutdown() { + RsuDepositor testRsuDepositor = new RsuDepositor(rsuProperties, securityServicesProperties.getIsRsuSigningEnabled()); + testRsuDepositor.shutdown(); + assertFalse(testRsuDepositor.isRunning()); + assertFalse(testRsuDepositor.isAlive()); + } + @Test + void testDeposit() { + RsuDepositor testRsuDepositor = new RsuDepositor(rsuProperties, securityServicesProperties.getIsRsuSigningEnabled()); + OdeTravelerInputData mockOdeTravelerInputData = new OdeTravelerInputData(); + testRsuDepositor.deposit(mockOdeTravelerInputData.getRequest(), "message"); + assertEquals(1, testRsuDepositor.getDepositorEntries().size()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesTest.java new file mode 100644 index 000000000..913207847 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesTest.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.security; + +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = SecurityServicesProperties.class) +class SecurityServicesPropertiesTest { + + @Autowired + SecurityServicesProperties securityServicesProperties; + + @Test + @Order(1) + void getSignatureEndpoint() { + assertEquals("http://localhost:8090/sign", securityServicesProperties.getSignatureEndpoint()); + } + + @Test + @Order(2) + void getSignatureEndpoint_DefaultWhenNoValueProvided() { + securityServicesProperties.setSignatureEndpoint(null); + assertEquals("http://test-host:1234/sign", securityServicesProperties.getSignatureEndpoint()); + } + + @Test + void getHostIP() { + assertEquals("test-host", securityServicesProperties.getHostIP()); + } + + @Test + void getPort() { + assertEquals(1234, securityServicesProperties.getPort()); + } + + @Test + void isSdwEnabled_DefaultsToTrueWhenNoValueProvided() { + assertTrue(securityServicesProperties.getIsSdwSigningEnabled()); + } + + @Test + void isRsuEnabled_DefaultsToFalseWhenNoValueProvided() { + assertFalse(securityServicesProperties.getIsRsuSigningEnabled()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidatorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidatorTest.java new file mode 100644 index 000000000..67556a3b8 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/security/SecurityServicesPropertiesValidatorTest.java @@ -0,0 +1,72 @@ +package us.dot.its.jpo.ode.security; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class SecurityServicesPropertiesValidatorTest { + + @Test + void supports() { + SecurityServicesPropertiesValidator validator = new SecurityServicesPropertiesValidator(); + assertTrue(validator.supports(SecurityServicesProperties.class)); + assertFalse(validator.supports(Object.class)); + } + + @Test + void validate() { + SecurityServicesProperties properties = new SecurityServicesProperties(); + properties.setIsRsuSigningEnabled(true); + properties.setIsSdwSigningEnabled(true); + properties.setSignatureEndpoint("http://localhost:8080/sign"); + + SecurityServicesPropertiesValidator validator = new SecurityServicesPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertFalse(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidSignatureEndpoint() { + SecurityServicesProperties properties = new SecurityServicesProperties(); + properties.setIsRsuSigningEnabled(true); + properties.setIsSdwSigningEnabled(true); + properties.setSignatureEndpoint("localhost:8080/sign"); + + SecurityServicesPropertiesValidator validator = new SecurityServicesPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidHostIP() { + SecurityServicesProperties properties = new SecurityServicesProperties(); + properties.setIsRsuSigningEnabled(true); + properties.setIsSdwSigningEnabled(true); + properties.setHostIP(null); + properties.setPort(8080); + + SecurityServicesPropertiesValidator validator = new SecurityServicesPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidPort() { + SecurityServicesProperties properties = new SecurityServicesProperties(); + properties.setIsRsuSigningEnabled(true); + properties.setIsSdwSigningEnabled(true); + properties.setHostIP("localhost"); + + SecurityServicesPropertiesValidator validator = new SecurityServicesPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index 8decd40ff..11b152d47 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -26,9 +26,11 @@ import mockit.Mocked; import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeTravelerInputData; +import us.dot.its.jpo.ode.rsu.RsuProperties; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.services.asn1.Asn1CommandManager.Asn1CommandManagerException; import us.dot.its.jpo.ode.snmp.SnmpSession; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -38,15 +40,18 @@ public class Asn1CommandManagerTest { @Tested Asn1CommandManager testAsn1CommandManager; - @Injectable - OdeProperties injectableOdeProperties; - @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @Injectable SDXDepositorTopics injectableSDXDepositorTopics; + @Injectable + RsuProperties injectableRsuProperties; + + @Injectable + SecurityServicesProperties injectableSecurityServicesProperties; + @Capturing MessageProducer capturingMessageProducer; @Capturing diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java index a0ff1680d..1350a875e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java @@ -24,13 +24,9 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; -import mockit.Injectable; import mockit.Mocked; import mockit.Tested; -import us.dot.its.jpo.ode.OdeProperties; -import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; import us.dot.its.jpo.ode.util.XmlUtils; @@ -42,8 +38,6 @@ public class Asn1DecodedDataRouterTest { @Tested Asn1DecodedDataRouter testAsn1DecodedDataRouter; - @Injectable - OdeProperties injectableOdeProperties; // @SuppressWarnings("rawtypes") // @Capturing diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouterTest.java index 00f2b2953..d18fcaba0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouterTest.java @@ -21,25 +21,19 @@ import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import mockit.Capturing; import mockit.Expectations; -import mockit.Injectable; import mockit.Mocked; import mockit.Tested; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.traveler.TimTransmogrifier; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -import us.dot.its.jpo.ode.wrapper.MessageProducer; public class Asn1EncodedDataRouterTest { @Tested Asn1EncodedDataRouter testAsn1EncodedDataRouter; - - @Injectable - OdeProperties injectableOdeProperties; + // @Capturing // MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java index b25c78dc4..60519d012 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java @@ -19,16 +19,15 @@ import mockit.Injectable; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.*; +import us.dot.its.jpo.ode.rsu.RsuProperties; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import static org.junit.Assert.assertNotNull; class AsnCodecRouterServiceControllerTest { - @Injectable - OdeProperties injectableOdeProperties; @Injectable OdeKafkaProperties odeKafkaProperties; @Injectable @@ -39,6 +38,10 @@ class AsnCodecRouterServiceControllerTest { Asn1CoderTopics asn1CoderTopics; @Injectable SDXDepositorTopics sdxDepositorTopics; + @Injectable + RsuProperties rsuProperties; + @Injectable + SecurityServicesProperties securityServicesProperties; @Test @Disabled @@ -51,6 +54,6 @@ void shouldStartTwoConsumers() { } }; - assertNotNull(new AsnCodecRouterServiceController(injectableOdeProperties, odeKafkaProperties, jsonTopics, pojoTopics, asn1CoderTopics, sdxDepositorTopics)); + assertNotNull(new AsnCodecRouterServiceController(odeKafkaProperties, jsonTopics, pojoTopics, asn1CoderTopics, sdxDepositorTopics, rsuProperties, securityServicesProperties)); } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java index 950fdf362..aab7614bf 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java @@ -10,7 +10,6 @@ import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index b9e704123..b3555cee0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -8,7 +8,6 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 14a330d00..823f79134 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -8,7 +8,6 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index 5cf14ae26..751aee5fc 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -8,7 +8,6 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java index ba1b2ecf4..7aec1623d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java @@ -7,7 +7,6 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java index 1a3f905e2..e259303a4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonConverterTest.java @@ -22,7 +22,6 @@ import mockit.Mocked; import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -30,9 +29,7 @@ public class ToJsonConverterTest { @Tested ToJsonConverter testToJsonConverter; - - @Injectable - OdeProperties mockOdeProperties; + @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @Injectable diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java index 7090d2ef6..58b4ab4c5 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java @@ -21,7 +21,6 @@ import mockit.Injectable; import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java index 16624faa9..65674eae1 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/snmp/SnmpSessionTest.java @@ -211,8 +211,6 @@ public void shouldCreatePDUWithNTCIP1218Protocol_dataSigningEnabledRsu_False() t SNMP testParams = new SNMP(rsuSRMPsid, 0, 0, rsuSRMTxChannel, rsuSRMTxInterval, "2017-12-02T17:47:11-05:00", "2017-12-02T17:47:11-05:00", rsuSRMEnable, rsuSRMStatus); - System.setProperty("DATA_SIGNING_ENABLED_RSU", "false"); - boolean rsuDataSigningEnabled = false; // execute diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java index 64293e8a7..e93bade43 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/storage/FileSystemStorageServiceTest.java @@ -46,7 +46,7 @@ import mockit.Expectations; import mockit.Mocked; import mockit.Verifications; -import us.dot.its.jpo.ode.OdeProperties; +import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.eventlog.EventLogger; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDeleteControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDeleteControllerTest.java index 1721cda64..ae7cd763e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDeleteControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDeleteControllerTest.java @@ -20,6 +20,7 @@ import java.io.IOException; +import mockit.*; import org.junit.jupiter.api.Test; import org.snmp4j.PDU; import org.snmp4j.Snmp; @@ -27,22 +28,17 @@ import org.snmp4j.event.ResponseEvent; import org.springframework.http.HttpStatus; -import mockit.Capturing; -import mockit.Expectations; -import mockit.Injectable; -import mockit.Mocked; -import mockit.Tested; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.snmp.SnmpSession; public class TimDeleteControllerTest { @Tested TimDeleteController testTimDeleteController; - + @Injectable - OdeProperties injectableOdeProperties; + RsuProperties injectableRsuProperties; @Capturing SnmpSession capturingSnmpSession; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 481d6515a..5557dcd31 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -30,12 +30,12 @@ import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.kafka.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; +import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; @@ -47,9 +47,6 @@ public class TimDepositControllerTest { @Tested TimDepositController testTimDepositController; - @Injectable - OdeProperties injectableOdeProperties; - @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @@ -65,6 +62,9 @@ public class TimDepositControllerTest { @Injectable TimIngestTrackerProperties injectableTimIngestTrackerProperties; + @Injectable + SecurityServicesProperties injectableSecurityServicesProperties; + @Capturing MessageProducer capturingMessageProducer; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java index fc216b254..fff9aecdd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimQueryControllerTest.java @@ -24,8 +24,8 @@ import org.snmp4j.smi.VariableBinding; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.snmp.SnmpSession; import java.io.IOException; @@ -39,7 +39,7 @@ class TimQueryControllerTest { TimQueryController testTimQueryController; @Injectable - OdeProperties mockOdeProperties; + RsuProperties mockRsuProperties; @Capturing SnmpSession capturingSnmpSession; @@ -181,7 +181,7 @@ void snmpSessionListenExceptionShouldReturnError_ntcip1218RSU() { void testNullResponseReturnsTimeout() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -201,7 +201,7 @@ void testNullResponseReturnsTimeout() throws IOException { void testNullResponseReturnsTimeout_fourDot1RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -221,7 +221,7 @@ void testNullResponseReturnsTimeout_fourDot1RSU() throws IOException { void testNullResponseReturnsTimeout_ntcip1218RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -241,7 +241,7 @@ void testNullResponseReturnsTimeout_ntcip1218RSU() throws IOException { void testNullResponseResponseReturnsTimeout() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -264,7 +264,7 @@ void testNullResponseResponseReturnsTimeout() throws IOException { void testNullResponseResponseReturnsTimeout_fourDot1RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -287,7 +287,7 @@ void testNullResponseResponseReturnsTimeout_fourDot1RSU() throws IOException { void testNullResponseResponseReturnsTimeout_ntcip1218RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -310,7 +310,7 @@ void testNullResponseResponseReturnsTimeout_ntcip1218RSU() throws IOException { void testSuccessfulQuery() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -336,7 +336,7 @@ void testSuccessfulQuery() throws IOException { void testSuccessfulQuery_fourDot1RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -362,7 +362,7 @@ void testSuccessfulQuery_fourDot1RSU() throws IOException { void testSuccessfulQuery_ntcip1218RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -388,7 +388,7 @@ void testSuccessfulQuery_ntcip1218RSU() throws IOException { void testSuccessfulPopulatedQuery() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -417,7 +417,7 @@ void testSuccessfulPopulatedQuery() throws IOException { void testSuccessfulPopulatedQuery_fourDot1RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); @@ -446,7 +446,7 @@ void testSuccessfulPopulatedQuery_fourDot1RSU() throws IOException { void testSuccessfulPopulatedQuery_ntcip1218RSU() throws IOException { new Expectations() { { - mockOdeProperties.rsuProperties().getSrmSlots(); + mockRsuProperties.getSrmSlots(); result = 1; capturingSnmpSession.getSnmp(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 5af7cf4d6..acdc24ab1 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -2,10 +2,14 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import mockit.*; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import us.dot.its.jpo.ode.OdeProperties; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; @@ -13,10 +17,9 @@ import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.SituationDataWarehouse.SDW; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; -import us.dot.its.jpo.ode.plugin.j2735.DdsGeoRegion; import us.dot.its.jpo.ode.plugin.j2735.OdeGeoRegion; -import us.dot.its.jpo.ode.plugin.j2735.builders.GeoRegionBuilder; import us.dot.its.jpo.ode.plugin.j2735.timstorage.TravelerInputData; +import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.traveler.TimTransmogrifier.TimTransmogrifierException; import us.dot.its.jpo.ode.util.DateTimeUtils; import us.dot.its.jpo.ode.util.JsonUtils; @@ -27,262 +30,242 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; -import static org.junit.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = RsuProperties.class) class TimTransmogrifierTest { - @Mocked - OdeProperties mockOdeProperties; - - private static String schemaVersion = "7"; - - @Test - void testGetRsu() { - new Expectations() { - { - mockOdeProperties.rsuProperties().getUsername(); - result = "v3user"; - - mockOdeProperties.rsuProperties().getPassword(); - result = "password"; - } - }; - - RSU expected = new RSU("127.0.0.1", "v3user", "password", 1, 2000); - - // rsuUsername and rsuPassword are null - RSU actual1 = new RSU("127.0.0.1", null, null, 1, 2000); - TimTransmogrifier.updateRsuCreds(actual1, mockOdeProperties); - assertEquals(expected, actual1); - - // rsuUsername and rsuPassword are not-null - RSU actual2 = new RSU("127.0.0.1", "v3user", "password", 1, 2000); - TimTransmogrifier.updateRsuCreds(actual2, mockOdeProperties); - assertEquals(expected, actual2); - - // rsuUsername and rsuPassword are blank - RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); - TimTransmogrifier.updateRsuCreds(actual3, mockOdeProperties); - assertEquals(expected, actual3); - } - - @Test - void testObfuscateRsuPassword() { - String actual = TimTransmogrifier.obfuscateRsuPassword( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); - assertEquals( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", - actual); - } - - void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) - throws JsonUtilsException, XmlUtilsException { - JsonNode obj = JsonUtils.toObjectNode(array); - JsonNode oldObj = obj.get(arrayKey); - - JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); - String actualXml = XmlUtils.toXmlStatic(newObj); - - assertEquals(expectedXml, actualXml); - } - - @Test - void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { - String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String singleXmlExpected = "127.0.0.3v3userpassword1100010"; - assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); - - String multi = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String multiXmlExpected = "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; - assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, multiXmlExpected); - } - - @Test - void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); - assertNull(actualASD); - } - - @Test - void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() throws TimTransmogrifierException { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - inputServiceRequest.setSnmp(new SNMP()); - - try { - TimTransmogrifier.buildASD(inputServiceRequest); - fail("Expected TimTransmogrifierException"); - } catch (Exception e) { - assertTrue(e instanceof TimTransmogrifierException); - } - } - - @Test - void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() throws TimTransmogrifierException { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - - try { - TimTransmogrifier.buildASD(inputServiceRequest); - fail("Expected TimTransmogrifierException"); - } catch (Exception e) { - assertTrue(e instanceof TimTransmogrifierException); - } - } - - @Test - void testBuildASDValidTimeFromSNMP(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException { - - SNMP inputSNMP = new SNMP(); - inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - inputServiceRequest.setSnmp(inputSNMP); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - void testBuildASDValidTimeFromSDW(@Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException { - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - void testConvertToXMLASD(@Capturing DateTimeUtils capturingDateTimeUtils, - @Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { - - new Expectations() { - { - DateTimeUtils.now(); - result = "timeTime"; - } - }; - - new MockUp() { - @Mock - DdsGeoRegion ddsGeoRegion(OdeGeoRegion serviceRegion) { - return new DdsGeoRegion(); - } - }; - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, staticSerialId); - String expected = String.format("us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F0000000017876BA7F2030000000000331", schemaVersion); - assertEquals(expected, actualXML); - } - - @Test - void testConvertToXMLMessageFrame(@Capturing DateTimeUtils capturingDateTimeUtils, - @Capturing GeoRegionBuilder capturingGeoRegionBuilder) - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException { - - new Expectations() { - { - DateTimeUtils.now(); - result = "timeTime"; - } - }; - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); - var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000timeTime%s0falsethirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", schemaVersion); - assertEquals(expected,actualXML); - } - - @Test - void testCreateOdeTimData() throws JsonUtilsException { - - JSONObject testObject = JsonUtils - .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); - JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); - - assertEquals( - "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", - actualOdeTimData.toString()); - } - - @Test - void testConstructorIsPrivate() - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { - - Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - try { - constructor.newInstance(); - fail("Expected IllegalAccessException.class"); - } catch (Exception e) { - assertEquals(InvocationTargetException.class, e.getClass()); - } - } + @Autowired + RsuProperties rsuProperties; + + private static final String schemaVersion = "7"; + + @Test + void testUpdateRsuCreds_UpdateWhenNull() { + RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + + RSU actual = new RSU("127.0.0.1", null, null, 1, 2000); + TimTransmogrifier.updateRsuCreds(actual, rsuProperties); + + assertEquals(expected, actual); + } + + @Test + void testUpdateRsuCreds_DoNotOverwriteExisting() { + RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + + RSU actual = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + TimTransmogrifier.updateRsuCreds(actual, rsuProperties); + + assertEquals(expected, actual); + } + + @Test + void testUpdateRsuCreds_UpdatedWhenEmptyString() { + RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(),1, 2000); + // rsuUsername and rsuPassword are blank + RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); + TimTransmogrifier.updateRsuCreds(actual3, rsuProperties); + assertEquals(expected, actual3); + } + + @Test + void testObfuscateRsuPassword() { + String actual = TimTransmogrifier.obfuscateRsuPassword( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); + assertEquals( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", + actual); + } + + void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) + throws JsonUtilsException, XmlUtilsException { + JsonNode obj = JsonUtils.toObjectNode(array); + JsonNode oldObj = obj.get(arrayKey); + + JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); + String actualXml = XmlUtils.toXmlStatic(newObj); + + assertEquals(expectedXml, actualXml); + } + + @Test + void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { + String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String singleXmlExpected = "127.0.0.3v3userpassword1100010"; + assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); + + String multi = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String multiXmlExpected = "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; + assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, multiXmlExpected); + } + + @Test + void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); + assertNull(actualASD); + } + + @Test + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + inputServiceRequest.setSnmp(new SNMP()); + + assertThrows(TimTransmogrifierException.class, () -> TimTransmogrifier.buildASD(inputServiceRequest)); + } + + @Test + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + + assertThrows(TimTransmogrifierException.class, () -> TimTransmogrifier.buildASD(inputServiceRequest)); + } + + @Test + void testBuildASDValidTimeFromSNMP() + throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { + + SNMP inputSNMP = new SNMP(); + inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); + + SDW inputSDW = new SDW(); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setSnmp(inputSNMP); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + void testBuildASDValidTimeFromSDW() + throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + void testConvertToXMLASD() + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, OdeGeoRegion.GeoRegionException { + + Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:00:15.190Z"), ZoneId.of("UTC")); + DateTimeUtils.setClock(fixedClock); + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, staticSerialId); + String expected = String.format("us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F000000001425379030-834779030423057530-8284275307876BA7F20320176117472018311747331", DateTimeUtils.now(), schemaVersion); + assertEquals(expected, actualXML); + } + + @Test + void testConvertToXMLMessageFrame() + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, OdeGeoRegion.GeoRegionException { + + Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:36:15.170Z"), ZoneId.of("UTC")); + DateTimeUtils.setClock(fixedClock); + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); + var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", DateTimeUtils.now(), schemaVersion); + assertEquals(expected, actualXML); + } + + @Test + void testCreateOdeTimData() throws JsonUtilsException { + + JSONObject testObject = JsonUtils + .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); + JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); + + assertEquals( + "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", + actualOdeTimData.toString()); + } + + @Test + void testConstructorIsPrivate() throws NoSuchMethodException { + + Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + + assertThrows(InvocationTargetException.class, constructor::newInstance); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java index 83d5e2e37..29a31b3eb 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java @@ -24,7 +24,6 @@ import org.springframework.http.HttpStatus; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.web.multipart.MultipartFile; -import us.dot.its.jpo.ode.OdeProperties; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; import us.dot.its.jpo.ode.kafka.FileTopics; @@ -46,9 +45,6 @@ class FileUploadControllerTest { @Mocked StorageService mockStorageService; - @Injectable - OdeProperties injectableOdeProperties; - @Injectable OdeKafkaProperties injectableOdeKafkaProperties; @@ -74,9 +70,6 @@ class FileUploadControllerTest { @Mocked ExecutorService mockExecutorService; - @Mocked - OdeProperties mockOdeProperties; - @Mocked MultipartFile mockMultipartFile; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/wrapper/MessageProducerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/wrapper/MessageProducerTest.java index 86b939d0e..130d7e4c2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/wrapper/MessageProducerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/wrapper/MessageProducerTest.java @@ -75,7 +75,6 @@ public void testSendWithTopic() { new MessageProducer("testBrokers", null, "testPartitioner", mockProps, Collections.singleton("testTopic")); - testMessageProducer.setProducer(mockProducer); testMessageProducer.send("testTopic", "testKey", "testValue"); } diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml index 8c14ff1e1..512cd14e0 100644 --- a/jpo-ode-svcs/src/test/resources/application.yaml +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -4,19 +4,29 @@ spring: max-file-size: 1MB max-request-size: 1MB ode: - host-ip: "test-host" - verbose-json: false - plugins-locations: "plugins" output-schema-version: 7 - security-svcs-port: 8090 - security-svcs-signature-endpoint: "sign" + security-services: + host-ip: "test-host" + port: 1234 + signature-endpoint: "http://localhost:8090/sign" + is-sdw-signing-enabled: + is-rsu-signing-enabled: rsu: srm-slots: 100 username: "test-username" password: "test-password" kafka: brokers: "localhost:9092" - producer-type: sync + producer: + type: "async" + acks: "0" + retries: 1 + batch-size: 1638 + linger-ms: 2 + buffer-memory: 33554433 + key-serializer: "org.apache.kafka.common.serialization.StringSerializer" + value-serializer: "org.apache.kafka.common.serialization.ByteArraySerializer" + partitioner-class: "org.apache.kafka.clients.producer.internals.DefaultPartitioner" disabled-topics: - "topic.OdeBsmRxPojo" - "topic.OdeBsmTxPojo" diff --git a/ppm.properties b/ppm.properties index a95735645..e69de29bb 100644 --- a/ppm.properties +++ b/ppm.properties @@ -1,35 +0,0 @@ -# Configuration details for the velocity filter. -# min and max velocity values are in units m/s per the J2735 specification. -privacy.filter.velocity=ON -privacy.filter.velocity.min=2.235 -privacy.filter.velocity.max=35.763 - -# Configuration details for privacy ID redaction. -privacy.redaction.id=ON -privacy.redaction.id.value=FFFFFFFF -privacy.redaction.id.inclusions=ON -privacy.redaction.id.included=BEA10000,BEA10001 - -# Configuration details for geofencing. -privacy.filter.geofence=ON -privacy.filter.geofence.mapfile=/ppm_data/road_file.csv -privacy.filter.geofence.sw.lat=40.997 -privacy.filter.geofence.sw.lon=-111.041 -privacy.filter.geofence.ne.lat=42.085 -privacy.filter.geofence.ne.lon=-104.047 - -# ODE / PPM Kafka topics. -privacy.topic.consumer=topic.OdeBsmJson -privacy.topic.producer=topic.FilteredOdeBsmJson - -group.id=0 - -# For testing purposes, use one partition. -privacy.kafka.partition=0 - -# The host ip address for the Broker. -metadata.broker.list=your.docker.host.ip:9092 - -# specify the compression codec for all data generated: none, gzip, snappy, lz4, zstd -compression.type=zstd - From c3333d4726e2524170e80c84eece95405564aff6 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:11:18 -0700 Subject: [PATCH 057/264] Address polish comments --- .../builders/SignalStatusListBuilder.java | 25 +++++++++-------- .../SignalStatusPackageListBuilder.java | 28 +++++++++---------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java index 61efbfe91..92ce4d67e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusListBuilder.java @@ -15,21 +15,22 @@ public static J2735SignalStatusList genericSignalStatusList(JsonNode status) { J2735SignalStatusList signalStatusList = new J2735SignalStatusList(); JsonNode signalStatus = status.get("SignalStatus"); - if(signalStatus != null) - { - if (signalStatus.isArray()) { - Iterator elements = signalStatus.elements(); - - while (elements.hasNext()) { - signalStatusList.getStatus() - .add(SignalStatusBuilder.genericSignalStatus(elements.next())); - } - } else { + if(signalStatus == null) { + return null; + } + + if (signalStatus.isArray()) { + Iterator elements = signalStatus.elements(); + + while (elements.hasNext()) { signalStatusList.getStatus() - .add(SignalStatusBuilder.genericSignalStatus(signalStatus)); + .add(SignalStatusBuilder.genericSignalStatus(elements.next())); } + } else { + signalStatusList.getStatus() + .add(SignalStatusBuilder.genericSignalStatus(signalStatus)); } - + return signalStatusList; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java index 4f550cc00..7d5b98f7f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/SignalStatusPackageListBuilder.java @@ -15,23 +15,21 @@ public static J2735SignalStatusPackageList genericSignalStatusPackageList(JsonNo J2735SignalStatusPackageList signalStatusPackageList = new J2735SignalStatusPackageList(); JsonNode signalStatusPackage = sigStatus.get("SignalStatusPackage"); - if(signalStatusPackage != null) - { - if (signalStatusPackage.isArray()) { - Iterator elements = signalStatusPackage.elements(); - - while (elements.hasNext()) { - signalStatusPackageList.getSigStatus() - .add(SignalStatusPackageBuilder.genericSignalStatusPackage(elements.next())); - } - } else { + if(signalStatusPackage == null) { + return null; + } + + if (signalStatusPackage.isArray()) { + Iterator elements = signalStatusPackage.elements(); + + while (elements.hasNext()) { signalStatusPackageList.getSigStatus() - .add(SignalStatusPackageBuilder.genericSignalStatusPackage(signalStatusPackage)); - + .add(SignalStatusPackageBuilder.genericSignalStatusPackage(elements.next())); } - } - else { - return null; + } else { + signalStatusPackageList.getSigStatus() + .add(SignalStatusPackageBuilder.genericSignalStatusPackage(signalStatusPackage)); + } return signalStatusPackageList; From e5187ba4a7606a62c28dd8c333741ed43cdfe1b0 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Mon, 18 Nov 2024 14:06:23 -0700 Subject: [PATCH 058/264] Add Approval Tests for MAP Data Flows (#116) * Migrate kafka configuration values to ODEKafkaProperties This is the first part of the work needed to separate the OdeProperties into multpile more manageable chunks. It introduces the usage of application.yaml and @Autowired in tests to more fully utilize the Spring framework. * remove @Component annotation and accept linter errors Adding the @Component annotation to the *Receivers caused double instantiations and port binding issues * migrate from application.properties to application.yaml and introducde host-ip config val * add make restart target for easier, faster restarts that don't require a full image rebuild * add missing getHostId test for odekafkaproperties * move odekafkaproperties to kafka package * correctly declare restart target as PHONY in Makefile * move OdeKafkaPropertiesTest to correct test package * add tests to OdePropertiesTest for hostIP and remove unused imports and variables * moved hostID from OdeKafkaProperties to AppContext to keep scope of new class small and directed * correct application.yaml's disabled-topics block * correct formatting in Asn1*JSONTest.java files and fix Sonarlint errors All swaps of argument positions in the mentioned tests are to align the function calls to the defition: assert*(expected, actual). Before this swap, the call was made in the tests like assert*(actual, expected) which has the same outcome when tests *pass* but is confusing when tests do not pass because the failure output will have the actual and expected values swapped in the message. * replace complex if-else nest with simpler switch statments in decoded data router * extract BSM properties from OdeProperties * correct application.yaml indentation for bsm block * reformat GenericReceiver * if-else to switch and pull logic out of nested if-block where possible * define topics structure in application.yaml * convert MessagePublisher to interface and implement in existing publishers * ImporterDirectoryWatcher properties and necessary refactors for related classes * Complete refactoring of UdpServicesController w/ intro of UDPReceiverProperties * add sprint.http.multipart config values to application.yaml * Add TODO for @mcook42 to update README.md with corrected instructions once OdeProperties refactor is completed * remove remaining references to kafka properties from OdeProperties * remove dead test code and add missing constructor param to ImporterDirectoryWatcherTest.java * finalize application.yaml topics structure and config classes * asn1decoder flows updated with new configuration objects * asn1encoder flows updated with new configuration objects * FileSystemStorageService refactor to use new configuration properties * delete unused BSMReceiverPropertiesTest.java * File-related controllers and watchers corrected for new configuration objects * Update TimDepositController with new topics configs * ByteArrayPublisher correct config usage * TimTransmorgrifierTest corrections * LogFileToAsn1CodecPublisherTest corrections * Revert "TimTransmorgrifierTest corrections" This reverts commit 2a27569087ce82d9e392bb1eb67ff26fcc04f7a7. * Trivial JMockit test fixes via \@Inject annotations * update test application.yaml * test application.yaml and OdeKafkaPropertiesTest correction * explicitly initialize OdeDataPublisher in OdeDataPublisherTest to avoid JMockit limitations with Set mocking * Adjust ImporterDirectoryWatcherTest.java to confirm directory creation instead of trying to run .run() It doesn't make much sense to test the scheduledExecutor when we already have a test suite for the ImporterProcessor called by the scheduled executor. JMockit doesn't play nicely (easily) with Spring configuration objects, so in the interest of time I refactored this test suite to confirm that we create the necessary directories without the use of JMockit. * OdeStringPublisherTest corrections to avoid JMockit Set mocking limitations * Replace unintentionally deleted license header in MessagePublisher * remove unnecessary comments from UdpServicesController * added missing tests for new configs in kafka package * reformatted LogFileToAsn1CodecPublisher for readability * pull RSUProperties up and refactor tests for clarity in OdePropertiesTest and TimTransmogrifierTest * remove redundant @Value annotations from OdeKafkaProperties * add missing AbstractUdpReceiverPublisher slf4j annotation * typo fixes, renames, and comment correction for LogFileToAsn1CodecPublisher and RSUProperties * remove dead/incorrect comment from TimDepositController * pull kafka env vars into OdeKafkaProperties * update SerializableMessageProducerPoolTest to use Spring and JUnit Jupiter for consistent and easier testing * standardize bean injection of RSU in OdeProperties * allow for use of fixed instant clock in DateTimeUtils to enable usage in unit tests * extract RsuProperties from OdeProperties and pull DATA_SIGNING_ENABLED_RSU var into application.yaml * extract SecurityServicesProperties and add SecurityServicesPropertiesValidator validation * test SecurityServicesProperties and add default values from comment in sample.env * implement CustomConversionServiceConfig to provide conversion of empty environment variables for Integer properties * remove unused KAFKA_TYPE from application.yaml * correct warnings in Dockerfile - maintainer -> label and no-cache * add **/.*iml to .gitignore * add validation to OdeKafkaProperties after runtime exception was thrown during testing * remove all dead references to OdeProperties from various files * Update README.md and UserGuide.md with new app configuration instructions. I removed the dead/outdated configuration table from UserGuide.md in favor of the self-documenting configuration objects and their Validation classes. This will keep the code and available configuration values up-to-date automatically instead of requiring developers to maintain these both in code and in documentation. * Asn1CommandManagerTest and SecurityServicesPropertiesValidator test updates for better validation * add @Import annotation to InetPacketSenderTest to ensure EventLogger is available during test runs * correct the OdeKafkaProperties validation * remove unused ppm.properties file * undo duplicate code extraction into function - makes code less clear, and is untested, so best to return to how it was * undo star imports in SnmpSession * use assertThrows instead of catching and asserting exception class in TimTransmogrifierTest * correct typo in TimDepositController comment, remove getters and setters from SerializableMessageProducerPool * add slf4j annotation to ImporterProcessor * use the correct environment variable names for tim-ingest-monitoring in application.yaml * add @Import annotation to InetPacketSenderTest to ensure EventLogger is available during test runs * replace EventLogger with slf4j logger in InetPacketSenderTest * replace EventLogger with slf4j logger in InetPacketSender * remove unused imports from InetPacketSenderTest * move OdeTimJsonTMCFiltered topic from OdeProperties to JsonTopics after merge * move compression type into OdeKafkaProperties * use defaults from MessageProducer in OdeKafkaProperties for consistency * create POC test for MapReceiver to prove we can send UDP message in Integration Tests * can produce to the correct kafka topic using a test container in MapReceiverIntegrationTest * OdeTimJsonTopologyTest remove unnecessary public access modifiers * Use embedded kafka to confirm UDP map receiver sends message to topic.OdeRawEncodedMAPJson via kafka * Read in test cases from file and compare produced messages with expected inputs. tests not passing and need static time provider * naively pull TestCase into own class with static deserialization method * throw InvalidPayloadException when decoding for better debugging and code flow. use slf4j log annotation * completed initial approval testing for MapReceiverIntegrationTest. Want to add more tests first * add Valid MAP with minimum data test case and tidied up test code * use EmbeddedKafka spring annotation to allow Spring to manage the Bean lifecycle between test runs * use EmbeddedKafka in Asn1Decode*JSONTests to reduce runtime from ~60s each to >1s * undo changes to testing log levels * set static schema version in setup method to make test runs consistent between IDE and cli * rename to MapReceiverTest for consistency with other kafka-using tests * remove unused test-containers dependencies from pom.xml * undo debugging changes in MapReceiver and MapReceiverTest * removed unused csv test data * add JSONEncodedMAP_to_Asn1DecoderInput_Validation.json as valid input data for approval testing thanks to @drewjj * introduce SupportedMessageType enum and throw StartFlagNotFoundException instead of returning magic string from stripDot2Header * removed old git artifact RSUProperties superseded by RsuProperties * add Approval Tests to Asn1DecodeMAPJSON flow * improve javadoc for stripTrailingZeros * renamed TestCase.java to ApprovalTestCase for clarity of intent and moved TestUDPClient to new testUtilities package * OdeTimJsonTopologyTest remove unnecessary public access modifiers * use static constants for topic names in Asn1DecodeMAPJSONTest * added new approval tests for Asn1DecodedDataRouterApprovalTest suite * added approval tests for Asn1DecodedDataRouter - MapTx and MapJson * unify tests in Asn1DecodedDataRouterApprovalTest and prepend TEST to topic names in Asn1DecodeMAPJSONTest for unique topic naming to avoid topic name conflicts across tests * Set kafka broker address to localhost:9093 in test application.yaml to ensure EmbeddedKafka broker doesn't fail to start up when a kafka broker is already running in a dev container on 9092 * Set kafka broker address to localhost:4242 in test application.yaml to ensure EmbeddedKafka broker doesn't fail to start up when a kafka broker is already running in a dev container on 9092 and 9093 * use asn1 encoded hex strings as inputs for MapReceiverTest instead of plain json objects --- .../us/dot/its/jpo/ode/util/JsonUtils.java | 38 +- .../its/jpo/ode/wrapper/MessageProducer.java | 1 - jpo-ode-svcs/pom.xml | 16 +- .../us/dot/its/jpo/ode/OdeProperties.java | 2 +- .../asn1/message/Asn1DecodeBSMJSON.java | 13 +- .../asn1/message/Asn1DecodeMAPJSON.java | 76 +- .../asn1/message/Asn1DecodePSMJSON.java | 11 +- .../asn1/message/Asn1DecodeSPATJSON.java | 11 +- .../asn1/message/Asn1DecodeSRMJSON.java | 11 +- .../asn1/message/Asn1DecodeSSMJSON.java | 11 +- .../asn1/message/Asn1DecodeTIMJSON.java | 11 +- .../jpo/ode/udp/InvalidPayloadException.java | 9 + .../us/dot/its/jpo/ode/udp/UdpHexDecoder.java | 202 +- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 3 + .../udp/controller/UDPReceiverProperties.java | 2 + .../jpo/ode/udp/generic/GenericReceiver.java | 3 + .../dot/its/jpo/ode/udp/map/MapReceiver.java | 6 + .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 3 + .../its/jpo/ode/udp/spat/SpatReceiver.java | 3 + .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 3 + .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 3 + .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 3 + .../ode/uper/StartFlagNotFoundException.java | 7 + .../jpo/ode/uper/SupportedMessageType.java | 20 + .../us/dot/its/jpo/ode/uper/UperUtil.java | 175 +- .../jpo/ode/kafka/OdeKafkaPropertiesTest.java | 2 +- .../Asn1DecodedDataRouterApprovalTest.java | 110 + .../asn1/message/Asn1DecodeBSMJSONTest.java | 6 +- .../asn1/message/Asn1DecodeMAPJSONTest.java | 65 +- .../asn1/message/Asn1DecodePSMJSONTest.java | 4 + .../asn1/message/Asn1DecodeSPATJSONTest.java | 4 + .../asn1/message/Asn1DecodeSRMJSONTest.java | 4 + .../asn1/message/Asn1DecodeSSMJSONTest.java | 4 + .../asn1/message/Asn1DecodeTIMJSONTest.java | 4 + .../ode/testUtilities/ApprovalTestCase.java | 49 + .../jpo/ode/testUtilities/TestUDPClient.java | 36 + .../its/jpo/ode/udp/map/MapReceiverTest.java | 124 + .../us/dot/its/jpo/ode/uper/UperUtilTest.java | 47 +- .../src/test/resources/application.yaml | 16 +- .../src/test/resources/logback-test.xml | 16 +- ...coderRouter_ApprovalTestCases_MapJson.json | 14099 ++++++++++++++++ ...derRouter_ApprovalTestCases_MapTxPojo.json | 14099 ++++++++++++++++ ...dedMAP_to_Asn1DecoderInput_Validation.json | 164 + .../UDPMAP_To_EncodedJSON_Validation.json | 68 + pom.xml | 15 +- 45 files changed, 29196 insertions(+), 383 deletions(-) create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/InvalidPayloadException.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/StartFlagNotFoundException.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/SupportedMessageType.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/JsonUtils.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/JsonUtils.java index 3798f0e6b..b8fad646d 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/JsonUtils.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/JsonUtils.java @@ -15,19 +15,9 @@ ******************************************************************************/ package us.dot.its.jpo.ode.util; -import java.io.IOException; -import java.math.BigDecimal; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map.Entry; - -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; @@ -37,7 +27,17 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.type.LogicalType; +import lombok.extern.slf4j.Slf4j; +import org.json.JSONObject; + + +import java.io.IOException; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; +@Slf4j public class JsonUtils { public static class JsonUtilsException extends Exception { @@ -50,12 +50,10 @@ public JsonUtilsException(String string, Exception e) { } - private static ObjectMapper mapper; - private static ObjectMapper mapper_noNulls; - private static Logger logger; + private static final ObjectMapper mapper; + private static final ObjectMapper mapper_noNulls; private JsonUtils() { - logger = LoggerFactory.getLogger(JsonUtils.class); } static { @@ -75,7 +73,7 @@ public static String toJson(Object o, boolean verbose) { try { return verbose ? mapper.writeValueAsString(o) : mapper_noNulls.writeValueAsString(o); } catch (JsonProcessingException e) { - e.printStackTrace(); + log.error("Error converting object to JSON", e); return ""; } } @@ -84,7 +82,7 @@ public static Object fromJson(String s, Class clazz) { try { return jacksonFromJson(s, clazz); } catch (JsonUtilsException e) { - e.printStackTrace(); + log.error("Error deserializing JSON tree to {}", clazz.getName(), e); return null; } } @@ -113,10 +111,6 @@ public static String newJson(String key, Object value) { return newObjectNode(key, value).toString(); } - public static ObjectNode cloneObjectNode(ObjectNode src) { - return src.deepCopy(); - } - public static ObjectNode newObjectNode(String key, Object value) { ObjectNode json = mapper.createObjectNode(); json.putPOJO(key, value); @@ -135,7 +129,7 @@ public static JsonNode getJsonNode(String tree, String fieldName) { node = jsonNode.get(fieldName); } catch (IOException e) { - logger.error("IOException", e); + log.error("IOException", e); } return node; } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index d52ab3315..824b4e247 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -16,7 +16,6 @@ package us.dot.its.jpo.ode.wrapper; import lombok.Getter; -import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; diff --git a/jpo-ode-svcs/pom.xml b/jpo-ode-svcs/pom.xml index 9a10b40bd..1f8508542 100644 --- a/jpo-ode-svcs/pom.xml +++ b/jpo-ode-svcs/pom.xml @@ -41,11 +41,6 @@ org.springframework.boot spring-boot-starter-thymeleaf - - org.springframework.boot - spring-boot-devtools - runtime - org.springframework.boot spring-boot-starter-data-rest @@ -73,6 +68,15 @@ org.springframework.boot spring-boot-starter-websocket + + org.springframework.kafka + spring-kafka + + + org.springframework.kafka + spring-kafka-test + test + org.webjars @@ -128,8 +132,6 @@ javax.annotation-api 1.3.2 - - ${project.artifactId} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index 626f3af9c..ffdf1784a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -31,7 +31,7 @@ @Slf4j public class OdeProperties { - private int outputSchemaVersion; + private int outputSchemaVersion = 7; private static final byte[] JPO_ODE_GROUP_ID = "jode".getBytes(); @Autowired diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index 5879866e9..f510fdd6c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeBsmMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodeBSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTo super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getBsmStartFlag() + SupportedMessageType.BSM.getStartFlag() ); } @@ -37,18 +39,15 @@ protected OdeAsn1Data process(String consumedData) { Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", EncodingRule.UPER); metadata.addEncoding(unsecuredDataEncoding); - String payloadHexString = ((JSONObject)((JSONObject) rawBsmJsonObject.get("payload")).get("data")).getString("bytes"); + String payloadHexString = ((JSONObject) ((JSONObject) rawBsmJsonObject.get("payload")).get("data")).getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-BSM DATA ENCOUNTERED IN THE ASN1DECODEBSMJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java index 919d7bd08..c890b8293 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java @@ -11,46 +11,46 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMapMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { - private final ObjectMapper objectMapper = new ObjectMapper(); - - public Asn1DecodeMAPJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super( - publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getMapStartFlag() - );} - - @Override - protected OdeAsn1Data process(String consumedData) { - OdeAsn1Data messageToPublish = null; - try { - JSONObject rawMapJsonObject = new JSONObject(consumedData); - - String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); - OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); - - Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", EncodingRule.UPER); - metadata.addEncoding(unsecuredDataEncoding); - - String payloadHexString = ((JSONObject)((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-MAP DATA ENCOUNTERED IN THE ASN1DECODEMAPJSON CLASS"); - return null; - } - - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - - messageToPublish = new OdeAsn1Data(metadata, payload); - publishEncodedMessageToAsn1Decoder(messageToPublish); - } catch (Exception e) { - log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); - } - return messageToPublish; - } + private final ObjectMapper objectMapper = new ObjectMapper(); + + public Asn1DecodeMAPJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { + super( + publishTopic, + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + SupportedMessageType.MAP.getStartFlag() + ); + } + + @Override + protected OdeAsn1Data process(String consumedData) { + OdeAsn1Data messageToPublish = null; + try { + JSONObject rawMapJsonObject = new JSONObject(consumedData); + + String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); + OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); + + Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", EncodingRule.UPER); + metadata.addEncoding(unsecuredDataEncoding); + + String payloadHexString = ((JSONObject) ((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); + + OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + + messageToPublish = new OdeAsn1Data(metadata, payload); + publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); + } catch (Exception e) { + log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); + } + return messageToPublish; + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index 014ce2110..515afa619 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodePSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTo super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getPsmStartFlag() + SupportedMessageType.PSM.getStartFlag() );} @Override @@ -39,15 +41,12 @@ protected OdeAsn1Data process(String consumedData) { String payloadHexString = ((JSONObject)((JSONObject) rawPsmJsonObject.get("payload")).get("data")).getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-PSM DATA ENCOUNTERED IN THE ASN1DECODEPSMJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index f48e21524..a3582b4f8 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSpatMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodeSPATJSON(OdeKafkaProperties odeKafkaProperties, String publishT super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getSpatStartFlag() + SupportedMessageType.SPAT.getStartFlag() ); } @@ -41,15 +43,12 @@ protected OdeAsn1Data process(String consumedData) { .getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-SPAT DATA ENCOUNTERED IN THE ASN1DECODESPATJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 0c6c0c5e4..56bca2426 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSrmMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodeSRMJSON(OdeKafkaProperties odeKafkaProperties, String publishTo super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getSrmStartFlag() + SupportedMessageType.SRM.getStartFlag() );} @Override @@ -40,15 +42,12 @@ protected OdeAsn1Data process(String consumedData) { .getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-SRM DATA ENCOUNTERED IN THE ASN1DECODESRMJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index 1ab2eceef..fe2c9485c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSsmMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodeSSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTo super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getSsmStartFlag() + SupportedMessageType.SSM.getStartFlag() );} @Override @@ -40,15 +42,12 @@ protected OdeAsn1Data process(String consumedData) { .getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-SSM DATA ENCOUNTERED IN THE ASN1DECODESSMJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index 788c8c6c6..6e86509cf 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -11,6 +11,8 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeTimMetadata; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; @Slf4j @@ -21,7 +23,7 @@ public Asn1DecodeTIMJSON(OdeKafkaProperties odeKafkaProperties, String publishTo super( publishTopic, new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - UperUtil.getTimStartFlag() + SupportedMessageType.TIM.getStartFlag() );} @Override @@ -39,15 +41,12 @@ protected OdeAsn1Data process(String consumedData) { String payloadHexString = ((JSONObject) ((JSONObject) rawTimJsonObject.get("payload")).get("data")).getString("bytes"); payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - if (payloadHexString.equals("BAD DATA")) { - log.error("NON-TIM DATA ENCOUNTERED IN THE ASN1DECODETIMJSON CLASS"); - return null; - } - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); messageToPublish = new OdeAsn1Data(metadata, payload); publishEncodedMessageToAsn1Decoder(messageToPublish); + } catch (StartFlagNotFoundException e) { + log.error("Unexpected data type encountered.", e); } catch (Exception e) { log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/InvalidPayloadException.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/InvalidPayloadException.java new file mode 100644 index 000000000..975b31dc7 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/InvalidPayloadException.java @@ -0,0 +1,9 @@ +package us.dot.its.jpo.ode.udp; + +public class InvalidPayloadException extends Exception { + private static final long serialVersionUID = 1L; + + public InvalidPayloadException(String message) { + super(message); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java index bd62c7d0f..b620ff2b2 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java @@ -1,14 +1,7 @@ package us.dot.its.jpo.ode.udp; -import java.net.DatagramPacket; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; - +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeBsmMetadata; @@ -30,47 +23,49 @@ import us.dot.its.jpo.ode.model.OdeTimMetadata; import us.dot.its.jpo.ode.model.ReceivedMessageDetails; import us.dot.its.jpo.ode.model.RxSource; +import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; +import us.dot.its.jpo.ode.util.DateTimeUtils; import us.dot.its.jpo.ode.util.JsonUtils; +import java.net.DatagramPacket; + +@Slf4j public class UdpHexDecoder { - - private static Logger logger = LoggerFactory.getLogger(UdpHexDecoder.class); - - public static OdeAsn1Payload getPayloadHexString(DatagramPacket packet, UperUtil.SupportedMessageTypes msgType) { - String startFlag = UperUtil.getStartFlag(msgType); - // extract the actual packet from the buffer - byte[] payload = packet.getData(); - if (payload == null) - return null; - // convert bytes to hex string and verify identity - String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); - if (payloadHexString.indexOf(startFlag) == -1) - return null; - - logger.debug("Full {} packet: {}", msgType, payloadHexString); - - payloadHexString = UperUtil.stripTrailingZeros(UperUtil.stripDot3Header(payloadHexString, startFlag)).toLowerCase(); - logger.debug("Stripped {} packet: {}", msgType, payloadHexString); - - OdeAsn1Payload odePayload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - - return odePayload; + + private UdpHexDecoder() { + throw new UnsupportedOperationException(); } - public static String buildJsonMapFromPacket(DatagramPacket packet){ + public static OdeAsn1Payload getPayloadHexString(DatagramPacket packet, SupportedMessageType msgType) throws InvalidPayloadException { + // extract the actual packet from the buffer + byte[] payload = packet.getData(); + if (payload == null) + throw new InvalidPayloadException("Payload is null"); + // convert bytes to hex string and verify identity + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + if (!payloadHexString.contains(msgType.getStartFlag())) + throw new InvalidPayloadException("Payload does not contain start flag"); + + log.debug("Full {} packet: {}", msgType, payloadHexString); + + payloadHexString = UperUtil.stripTrailingZeros(UperUtil.stripDot3Header(payloadHexString, msgType.getStartFlag())).toLowerCase(); + log.debug("Stripped {} packet: {}", msgType, payloadHexString); + + return new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + } + + public static String buildJsonMapFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload mapPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.MAP); - if (mapPayload == null) - return null; + OdeAsn1Payload mapPayload = getPayloadHexString(packet, SupportedMessageType.MAP); OdeMapMetadata mapMetadata = new OdeMapMetadata(mapPayload); - + // Add header data for the decoding process - mapMetadata.setOdeReceivedAt(getUtcTimeString()); + mapMetadata.setOdeReceivedAt(DateTimeUtils.now()); mapMetadata.setOriginIp(senderIp); mapMetadata.setMapSource(MapSource.RSU); @@ -79,21 +74,19 @@ public static String buildJsonMapFromPacket(DatagramPacket packet){ mapMetadata.setSecurityResultCode(SecurityResultCode.success); return JsonUtils.toJson(new OdeAsn1Data(mapMetadata, mapPayload), false); - } + } - public static String buildJsonSpatFromPacket(DatagramPacket packet){ + public static String buildJsonSpatFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload spatPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SPAT); - if (spatPayload == null) - return null; + OdeAsn1Payload spatPayload = getPayloadHexString(packet, SupportedMessageType.SPAT); OdeSpatMetadata spatMetadata = new OdeSpatMetadata(spatPayload); // Add header data for the decoding process - spatMetadata.setOdeReceivedAt(getUtcTimeString()); + spatMetadata.setOdeReceivedAt(DateTimeUtils.now()); spatMetadata.setOriginIp(senderIp); spatMetadata.setSpatSource(SpatSource.RSU); @@ -102,77 +95,70 @@ public static String buildJsonSpatFromPacket(DatagramPacket packet){ spatMetadata.setSecurityResultCode(SecurityResultCode.success); - return JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false); - } - - public static String buildJsonTimFromPacket(DatagramPacket packet){ + return JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false); + } + public static String buildJsonTimFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload timPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.TIM); - if (timPayload == null) - return null; + OdeAsn1Payload timPayload = getPayloadHexString(packet, SupportedMessageType.TIM); OdeTimMetadata timMetadata = new OdeTimMetadata(timPayload); // Add header data for the decoding process - timMetadata.setOdeReceivedAt(getUtcTimeString()); + timMetadata.setOdeReceivedAt(DateTimeUtils.now()); timMetadata.setOriginIp(senderIp); timMetadata.setRecordType(RecordType.timMsg); timMetadata.setRecordGeneratedBy(GeneratedBy.RSU); timMetadata.setSecurityResultCode(SecurityResultCode.success); return JsonUtils.toJson(new OdeAsn1Data(timMetadata, timPayload), false); - } - - public static String buildJsonBsmFromPacket(DatagramPacket packet){ - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); - - OdeAsn1Payload bsmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.BSM); - if (bsmPayload == null) - return null; - OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); - - // Set BSM Metadata values that can be assumed from the UDP endpoint - bsmMetadata.setOdeReceivedAt(getUtcTimeString()); - - ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); - OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( - "unavailable", - "unavailable", - "unavailable", - "unavailable", - "unavailable"); - receivedMessageDetails.setRxSource(RxSource.RSU); - receivedMessageDetails.setLocationData(locationData); - bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); - - bsmMetadata.setOriginIp(senderIp); - bsmMetadata.setBsmSource(BsmSource.EV); - bsmMetadata.setRecordType(RecordType.bsmTx); - bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); - bsmMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false); - } - - public static String buildJsonSsmFromPacket(DatagramPacket packet){ + } + + public static String buildJsonBsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + OdeAsn1Payload bsmPayload = getPayloadHexString(packet, SupportedMessageType.BSM); + OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); + + // Set BSM Metadata values that can be assumed from the UDP endpoint + bsmMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); + OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( + "unavailable", + "unavailable", + "unavailable", + "unavailable", + "unavailable"); + receivedMessageDetails.setRxSource(RxSource.RSU); + receivedMessageDetails.setLocationData(locationData); + bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); + + bsmMetadata.setOriginIp(senderIp); + bsmMetadata.setBsmSource(BsmSource.EV); + bsmMetadata.setRecordType(RecordType.bsmTx); + bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); + bsmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false); + } + + public static String buildJsonSsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload ssmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SSM); - if (ssmPayload == null) - return null; + OdeAsn1Payload ssmPayload = getPayloadHexString(packet, SupportedMessageType.SSM); OdeSsmMetadata ssmMetadata = new OdeSsmMetadata(ssmPayload); // Add header data for the decoding process - ssmMetadata.setOdeReceivedAt(getUtcTimeString()); + ssmMetadata.setOdeReceivedAt(DateTimeUtils.now()); ssmMetadata.setOriginIp(senderIp); ssmMetadata.setSsmSource(SsmSource.RSU); @@ -183,19 +169,17 @@ public static String buildJsonSsmFromPacket(DatagramPacket packet){ return JsonUtils.toJson(new OdeAsn1Data(ssmMetadata, ssmPayload), false); } - public static String buildJsonSrmFromPacket(DatagramPacket packet){ + public static String buildJsonSrmFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload srmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.SRM); - if (srmPayload == null) - return null; + OdeAsn1Payload srmPayload = getPayloadHexString(packet, SupportedMessageType.SRM); OdeSrmMetadata srmMetadata = new OdeSrmMetadata(srmPayload); // Add header data for the decoding process - srmMetadata.setOdeReceivedAt(getUtcTimeString()); + srmMetadata.setOdeReceivedAt(DateTimeUtils.now()); srmMetadata.setOriginIp(senderIp); srmMetadata.setSrmSource(SrmSource.RSU); @@ -206,18 +190,16 @@ public static String buildJsonSrmFromPacket(DatagramPacket packet){ return JsonUtils.toJson(new OdeAsn1Data(srmMetadata, srmPayload), false); } - public static String buildJsonPsmFromPacket(DatagramPacket packet){ + public static String buildJsonPsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { String senderIp = packet.getAddress().getHostAddress(); int senderPort = packet.getPort(); - logger.debug("Packet received from {}:{}", senderIp, senderPort); + log.debug("Packet received from {}:{}", senderIp, senderPort); // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload psmPayload = getPayloadHexString(packet, UperUtil.SupportedMessageTypes.PSM); - if (psmPayload == null) - return null; + OdeAsn1Payload psmPayload = getPayloadHexString(packet, SupportedMessageType.PSM); OdePsmMetadata psmMetadata = new OdePsmMetadata(psmPayload); // Add header data for the decoding process - psmMetadata.setOdeReceivedAt(getUtcTimeString()); + psmMetadata.setOdeReceivedAt(DateTimeUtils.now()); psmMetadata.setOriginIp(senderIp); psmMetadata.setPsmSource(PsmSource.RSU); @@ -227,12 +209,4 @@ public static String buildJsonPsmFromPacket(DatagramPacket packet){ return JsonUtils.toJson(new OdeAsn1Data(psmMetadata, psmPayload), false); } - - public static String getUtcTimeString(){ - ZonedDateTime utc = ZonedDateTime.now(ZoneOffset.UTC); - String timestamp = utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")); - return timestamp; - } - - } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index a8d0a6468..236ea68b5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -38,6 +39,8 @@ public void run() { bsmPublisher.publish(publishTopic, bsmJson); } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java index 9fdbb2ee7..0d0e8f72e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UDPReceiverProperties.java @@ -3,10 +3,12 @@ import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; @Configuration @ConfigurationProperties(prefix = "ode.receivers") @Data +@Primary public class UDPReceiverProperties { private ReceiverProperties generic; private ReceiverProperties bsm; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index c94a27bae..a65918d60 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -6,6 +6,7 @@ import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.uper.UperUtil; @@ -100,6 +101,8 @@ public void run() { } default -> log.debug("Unknown Message Type"); } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index 45612401f..bd6084f38 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -36,10 +37,15 @@ public void run() { if (mapJson != null) { mapPublisher.publish(this.publishTopic, mapJson); } + } else { + log.debug("Ignoring empty packet from {}", packet.getSocketAddress()); } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } } while (!isStopped()); } + } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index a9c49b829..32ce0d8d6 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -38,6 +39,8 @@ public void run() { psmPublisher.publish(this.publishTopic, psmJson); } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index d52e739ec..61c5d101b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -38,6 +39,8 @@ public void run() { spatPublisher.publish(this.publishTopic, spatJson); } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index de24c959e..e06d3a4aa 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -38,6 +39,8 @@ public void run() { srmPublisher.publish(publishTopic, srmJson); } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index 4f73012c4..326f2ce5d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -38,6 +39,8 @@ public void run() { ssmPublisher.publish(this.publishTopic, ssmJson); } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 1aa457139..0bfb0b9d0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -4,6 +4,7 @@ import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; +import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @@ -42,6 +43,8 @@ public void run() { } } + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/StartFlagNotFoundException.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/StartFlagNotFoundException.java new file mode 100644 index 000000000..dec63eb01 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/StartFlagNotFoundException.java @@ -0,0 +1,7 @@ +package us.dot.its.jpo.ode.uper; + +public class StartFlagNotFoundException extends Exception { + public StartFlagNotFoundException(String s) { + super(s); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/SupportedMessageType.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/SupportedMessageType.java new file mode 100644 index 000000000..08bc24a0a --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/SupportedMessageType.java @@ -0,0 +1,20 @@ +package us.dot.its.jpo.ode.uper; + +import lombok.Getter; + +@Getter +public enum SupportedMessageType { + BSM("0014"), + TIM("001f"), + SPAT("0013"), + SSM("001e"), + SRM("001d"), + MAP("0012"), + PSM("0020"); + + private final String startFlag; + + SupportedMessageType(String startFlag) { + this.startFlag = startFlag; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java index 04cb4cc46..b5c8f49d7 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java @@ -1,40 +1,28 @@ package us.dot.its.jpo.ode.uper; -import java.util.HashMap; - +import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import us.dot.its.jpo.ode.model.OdeMsgPayload; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; +import java.util.HashMap; + +@Slf4j public class UperUtil { - private static Logger logger = LoggerFactory.getLogger(UperUtil.class); - - // start flags for BSM, TIM, MAP, SPAT, SRM, SSM, and PSM - private static final String BSM_START_FLAG = "0014"; - private static final String TIM_START_FLAG = "001f"; - private static final String SPAT_START_FLAG = "0013"; - private static final String SSM_START_FLAG = "001e"; - private static final String SRM_START_FLAG = "001d"; - private static final String MAP_START_FLAG = "0012"; - private static final String PSM_START_FLAG = "0020"; - - public enum SupportedMessageTypes { - BSM, TIM, SPAT, SSM, SRM, MAP, PSM + + private UperUtil() { + throw new UnsupportedOperationException(); } // Strips the IEEE 1609.2 security header (if it exists) and returns the payload - public static String stripDot2Header(String hexString, String payload_start_flag) { + public static String stripDot2Header(String hexString, String payloadStartFlag) throws StartFlagNotFoundException { hexString = hexString.toLowerCase(); - int startIndex = findValidStartFlagLocation(hexString, payload_start_flag); + int startIndex = findValidStartFlagLocation(hexString, payloadStartFlag); if (startIndex == -1) - return "BAD DATA"; - String strippedPayload = stripTrailingZeros(hexString.substring(startIndex, hexString.length())); - return strippedPayload; + throw new StartFlagNotFoundException("Start flag" + payloadStartFlag + " not found in message"); + return stripTrailingZeros(hexString.substring(startIndex)); } /* @@ -46,32 +34,32 @@ public static byte[] stripDot3Header(byte[] packet, HashMap msgS String hexString = HexUtils.toHexString(packet); String hexPacketParsed = ""; - + for (String start_flag : msgStartFlags.values()) { int payloadStartIndex = findValidStartFlagLocation(hexString, start_flag); if (payloadStartIndex == -1){ continue; } - + String headers = hexString.substring(0, payloadStartIndex); - String payload = hexString.substring(payloadStartIndex, hexString.length()); - + String payload = hexString.substring(payloadStartIndex); + // Look for the index of the start flag of a signed 1609.2 header, if one exists int signedDot2StartIndex = headers.indexOf("038100"); if (signedDot2StartIndex == -1) hexPacketParsed = payload; else - hexPacketParsed = headers.substring(signedDot2StartIndex, headers.length()) + payload; + hexPacketParsed = headers.substring(signedDot2StartIndex) + payload; break; } - if (hexPacketParsed.equals("")) { + if (hexPacketParsed.isEmpty()) { hexPacketParsed = hexString; - logger.debug("Packet is not a BSM, TIM or Map message: " + hexPacketParsed); + log.debug("Packet is not a BSM, TIM or Map message: {}", hexPacketParsed); } else { - logger.debug("Base packet: " + hexPacketParsed); + log.debug("Base packet: {}", hexPacketParsed); hexPacketParsed = stripTrailingZeros(hexPacketParsed); - logger.debug("Stripped packet: " + hexPacketParsed); + log.debug("Stripped packet: {}", hexPacketParsed); } return HexUtils.fromHexString(hexPacketParsed); } @@ -81,24 +69,24 @@ public static byte[] stripDot3Header(byte[] packet, HashMap msgS * Will return the payload with a signed 1609.2 header if it is present. * Otherwise, returns just the payload. */ - public static String stripDot3Header(String hexString, String payload_start_flag) { - int payloadStartIndex = findValidStartFlagLocation(hexString,payload_start_flag); + public static String stripDot3Header(String hexString, String payloadStartFlag) { + int payloadStartIndex = findValidStartFlagLocation(hexString,payloadStartFlag); String headers = hexString.substring(0, payloadStartIndex); - String payload = hexString.substring(payloadStartIndex, hexString.length()); - logger.debug("Base payload: " + payload); + String payload = hexString.substring(payloadStartIndex); + log.debug("Base payload: {}", payload); String strippedPayload = stripTrailingZeros(payload); - logger.debug("Stripped payload: " + strippedPayload); + log.debug("Stripped payload: {}", strippedPayload); // Look for the index of the start flag of a signed 1609.2 header int signedDot2StartIndex = headers.indexOf("038100"); if (signedDot2StartIndex == -1) return strippedPayload; else - return headers.substring(signedDot2StartIndex, headers.length()) + strippedPayload; + return headers.substring(signedDot2StartIndex) + strippedPayload; } /** * Determines the message type based off the most likely start flag - * + * * @param payload The OdeMsgPayload to check the content of. */ public static String determineMessageType(OdeMsgPayload payload) { @@ -110,7 +98,7 @@ public static String determineMessageType(OdeMsgPayload payload) { messageType = determineHexPacketType(hexString); } catch (JsonUtilsException e) { - logger.error("JsonUtilsException while checking message header. Stacktrace: " + e.toString()); + log.error("JsonUtilsException while checking message header.", e); } return messageType; } @@ -118,20 +106,20 @@ public static String determineMessageType(OdeMsgPayload payload) { public static String determineHexPacketType(String hexString){ String messageType = ""; - HashMap flagIndexes = new HashMap(); - - flagIndexes.put("MAP", findValidStartFlagLocation(hexString, MAP_START_FLAG)); - flagIndexes.put("SPAT", findValidStartFlagLocation(hexString, SPAT_START_FLAG)); - flagIndexes.put("TIM", findValidStartFlagLocation(hexString, TIM_START_FLAG)); - flagIndexes.put("BSM", findValidStartFlagLocation(hexString, BSM_START_FLAG)); - flagIndexes.put("SSM", findValidStartFlagLocation(hexString, SSM_START_FLAG)); - flagIndexes.put("PSM", findValidStartFlagLocation(hexString, PSM_START_FLAG)); - flagIndexes.put("SRM", findValidStartFlagLocation(hexString, SRM_START_FLAG)); + HashMap flagIndexes = new HashMap<>(); + + flagIndexes.put("MAP", findValidStartFlagLocation(hexString, SupportedMessageType.MAP.getStartFlag())); + flagIndexes.put("SPAT", findValidStartFlagLocation(hexString, SupportedMessageType.SPAT.getStartFlag())); + flagIndexes.put("TIM", findValidStartFlagLocation(hexString, SupportedMessageType.TIM.getStartFlag())); + flagIndexes.put("BSM", findValidStartFlagLocation(hexString, SupportedMessageType.BSM.getStartFlag())); + flagIndexes.put("SSM", findValidStartFlagLocation(hexString, SupportedMessageType.SSM.getStartFlag())); + flagIndexes.put("PSM", findValidStartFlagLocation(hexString, SupportedMessageType.PSM.getStartFlag())); + flagIndexes.put("SRM", findValidStartFlagLocation(hexString, SupportedMessageType.SRM.getStartFlag())); int lowestIndex = Integer.MAX_VALUE; for (String key : flagIndexes.keySet()) { if (flagIndexes.get(key) == -1) { - logger.debug("This message is not of type " + key); + log.debug("This message is not of type {}", key); continue; } if (flagIndexes.get(key) < lowestIndex) { @@ -142,96 +130,45 @@ public static String determineHexPacketType(String hexString){ return messageType; } - public static int findValidStartFlagLocation(String hexString, String startFlag){ + public static int findValidStartFlagLocation(String hexString, String startFlag) { int index = hexString.indexOf(startFlag); - // If the message has a header, make sure not to missidentify the message by the header - - if(index == 0 || index == -1){ + // If the message has a header, make sure not to misidentify the message by the header + if (index == 0 || index == -1) { return index; + } else { + index = hexString.indexOf(startFlag, 4); } - else{ - index = hexString.indexOf(startFlag,4); - } - + // Make sure start flag is on an even numbered byte - while(index != -1 && index %2 != 0){ - index = hexString.indexOf(startFlag, index+1); + while (index != -1 && index % 2 != 0) { + index = hexString.indexOf(startFlag, index + 1); } return index; } - + /** - * Trims extra `00` bytes off of the end of an ASN1 payload string - * This is remove the padded bytes added to the payload when receiving ASN1 payloads - * - * @param payload The OdeMsgPayload as a string to trim. - */ + * Trims extra `00` bytes off of the end of an ASN1 payload string + * This is remove the padded bytes added to the payload when receiving ASN1 payloads + * and leaves one remaining byte of `00`s for decoding + * + * @param payload The OdeMsgPayload as a string to trim. + */ public static String stripTrailingZeros(String payload) { // Remove trailing '0's while (payload.endsWith("0")) { payload = payload.substring(0, payload.length() - 1); } - + // Ensure the payload length is even if (payload.length() % 2 != 0) { payload += "0"; } - + // Append '00' to ensure one remaining byte of '00's for decoding payload += "00"; - - return payload; - } - - // Get methods for message start flags - public static String getBsmStartFlag() { - return BSM_START_FLAG; - } - - public static String getTimStartFlag() { - return TIM_START_FLAG; - } - - public static String getSpatStartFlag() { - return SPAT_START_FLAG; - } - - public static String getSsmStartFlag() { - return SSM_START_FLAG; - } - public static String getSrmStartFlag() { - return SRM_START_FLAG; - } - - public static String getMapStartFlag() { - return MAP_START_FLAG; - } - - public static String getPsmStartFlag() { - return PSM_START_FLAG; - } - - public static String getStartFlag(SupportedMessageTypes msgType) { - switch (msgType) { - case SupportedMessageTypes.BSM: - return BSM_START_FLAG; - case SupportedMessageTypes.TIM: - return TIM_START_FLAG; - case SupportedMessageTypes.SPAT: - return SPAT_START_FLAG; - case SupportedMessageTypes.SSM: - return SSM_START_FLAG; - case SupportedMessageTypes.SRM: - return SRM_START_FLAG; - case SupportedMessageTypes.MAP: - return MAP_START_FLAG; - case SupportedMessageTypes.PSM: - return PSM_START_FLAG; - default: - return null; - } + return payload; } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java index 42aaaa951..4cb641334 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesTest.java @@ -22,7 +22,7 @@ class OdeKafkaPropertiesTest { @Test void testGetBrokers() { - assertEquals("localhost:9092", odeKafkaProperties.getBrokers()); + assertEquals("localhost:4242", odeKafkaProperties.getBrokers()); } @Test diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java new file mode 100644 index 000000000..acf13eecb --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java @@ -0,0 +1,110 @@ +package us.dot.its.jpo.ode.services.asn1; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.model.OdeMapData; +import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; +import us.dot.its.jpo.ode.wrapper.MessageConsumer; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class, RawEncodedJsonTopics.class}) +@EmbeddedKafka( + partitions = 1, + topics = { Asn1DecodedDataRouterApprovalTest.INPUT_TOPIC, Asn1DecodedDataRouterApprovalTest.OUTPUT_TOPIC_TX, Asn1DecodedDataRouterApprovalTest.OUTPUT_TOPIC_JSON }, + ports = 4242 +) +@DirtiesContext +class Asn1DecodedDataRouterApprovalTest { + + static final String INPUT_TOPIC = "topic.Asn1DecoderOutput"; + static final String OUTPUT_TOPIC_TX = "topic.OdeMapTxPojo"; + static final String OUTPUT_TOPIC_JSON = "topic.OdeMapJson"; + + @Autowired + EmbeddedKafkaBroker embeddedKafka; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Test + void testAsn1DecodedDataRouter() throws IOException { + List testCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); + + PojoTopics pojoTopics = new PojoTopics(); + pojoTopics.setTxMap(OUTPUT_TOPIC_TX); + + JsonTopics jsonTopics = new JsonTopics(); + jsonTopics.setMap(OUTPUT_TOPIC_JSON); + + Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeKafkaProperties, pojoTopics, jsonTopics); + + MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); + + asn1DecoderConsumer.setName("Asn1DecoderConsumer"); + decoderRouter.start(asn1DecoderConsumer, INPUT_TOPIC); + + Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); + DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); + Producer producer = producerFactory.createProducer(); + + Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); + + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(consumer, OUTPUT_TOPIC_TX, OUTPUT_TOPIC_JSON); + + for (ApprovalTestCase testCase : testCases) { + ProducerRecord producerRecord = new ProducerRecord<>(INPUT_TOPIC, 0, 0, testCase.getInput()); + producer.send(producerRecord); + + String received = KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_TX).value(); + ObjectMapper mapper = new ObjectMapper(); + OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); + OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); + assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), "Failed test case: " + testCase.getDescription()); + // discard the JSON output + KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_JSON); + } + + List jsonTestCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json"); + + for (ApprovalTestCase testCase : jsonTestCases) { + ProducerRecord producerRecord = new ProducerRecord<>(INPUT_TOPIC, 0, 0, testCase.getInput()); + producer.send(producerRecord); + + String received = KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_JSON).value(); + ObjectMapper mapper = new ObjectMapper(); + OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); + OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); + assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), "Failed test case: " + testCase.getDescription()); + } + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index a77203887..253a64e06 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -6,13 +6,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeBsmMetadata; @@ -22,6 +22,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputBSM"}, ports = 4242) class Asn1DecodeBSMJSONTest { private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java index aab7614bf..7e869ec04 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java @@ -1,27 +1,51 @@ package us.dot.its.jpo.ode.services.asn1.message; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMapMetadata; +import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; +import us.dot.its.jpo.ode.wrapper.MessageConsumer; + +import java.io.IOException; +import java.util.List; +import java.util.Map; import static org.junit.jupiter.api.Assertions.assertEquals; +import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; +@Slf4j @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class, RawEncodedJsonTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {Asn1DecodeMAPJSONTest.INPUT_TOPIC, Asn1DecodeMAPJSONTest.OUTPUT_TOPIC}, ports = 4242) class Asn1DecodeMAPJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + + static final String INPUT_TOPIC = "topic.OdeRawEncodedMAPJsonTEST"; + static final String OUTPUT_TOPIC = "topic.Asn1DecoderInputMAPTEST"; @Autowired OdeKafkaProperties odeKafkaProperties; @@ -29,10 +53,17 @@ class Asn1DecodeMAPJSONTest { @Autowired Asn1CoderTopics asn1CoderTopics; + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + private EmbeddedKafkaBroker embeddedKafka; + @Test void testProcess() throws JSONException { Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); // Validate the metadata @@ -48,4 +79,34 @@ void testProcess() throws JSONException { assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); } + + @Test + void testProcess_ApprovalTest() throws IOException { + String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; + List approvalTestCases = deserializeTestCases(path); + + Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeKafkaProperties, OUTPUT_TOPIC); + MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( + odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); + asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSONTest"); + asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, INPUT_TOPIC); + + Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); + DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); + Producer producer = producerFactory.createProducer(); + + Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer testConsumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, OUTPUT_TOPIC); + + for (ApprovalTestCase approvalTestCase : approvalTestCases) { + // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer + ProducerRecord r = new ProducerRecord<>(INPUT_TOPIC, approvalTestCase.getInput()); + producer.send(r); + + ConsumerRecord actualRecord = KafkaTestUtils.getSingleRecord(testConsumer, OUTPUT_TOPIC); + assertEquals(approvalTestCase.getExpected(), actualRecord.value(), approvalTestCase.getDescription()); + } + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index 026d114f6..aa2f7bb16 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; @@ -20,6 +22,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputPSM"}, ports = 4242) class Asn1DecodePSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index 23d1bc28c..9bc336bf4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; @@ -20,6 +22,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSPAT"}, ports = 4242) class Asn1DecodeSPATJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index b3555cee0..d9ccc1962 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; @@ -20,6 +22,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSRM"}, ports = 4242) class Asn1DecodeSRMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 823f79134..208cc0804 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; @@ -20,6 +22,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSSM"}, ports = 4242) class Asn1DecodeSSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index 751aee5fc..272b6d34d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -6,6 +6,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; @@ -21,6 +23,8 @@ @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputTIM"}, ports = 4242) class Asn1DecodeTIMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java new file mode 100644 index 000000000..7d28b64ba --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.testUtilities; + +import lombok.Getter; +import lombok.Setter; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +public class ApprovalTestCase { + + public String description; + public String input; + public String expected; + + public static List deserializeTestCases(String path) throws IOException { + return deserializeTestCases(path, ""); + } + + public static List deserializeTestCases(String path, String startFlag) throws IOException { + List cases = new ArrayList<>(); + File file = new File(path); + byte[] jsonData = Files.readAllBytes(file.toPath()); + JSONObject jsonObject = new JSONObject(new String(jsonData)); + + JSONArray jsonArray = jsonObject.getJSONArray("cases"); + + for (int i = 0; i < jsonArray.length(); i++) { + ApprovalTestCase approvalTestCase = new ApprovalTestCase(); + JSONObject json = jsonArray.getJSONObject(i); + + approvalTestCase.setDescription(json.getString("description")); + + Object input = json.get("input"); + approvalTestCase.setInput(startFlag + input.toString()); // Add the 2-byte length prefix to the input + + approvalTestCase.setExpected(json.get("expected").toString()); + + cases.add(approvalTestCase); + } + return cases; + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java new file mode 100644 index 000000000..da50ee6b1 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java @@ -0,0 +1,36 @@ +package us.dot.its.jpo.ode.testUtilities; + +import lombok.extern.slf4j.Slf4j; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; + +@Slf4j +public class TestUDPClient { + private DatagramSocket socket; + private InetAddress address; + private int sendPort; + + private byte[] buf; + + public TestUDPClient(int port) throws SocketException, UnknownHostException { + socket = new DatagramSocket(); + address = InetAddress.getByName("localhost"); + sendPort = port; + } + + public void send(String msg) throws IOException { + buf = msg.getBytes(); + DatagramPacket packet = new DatagramPacket(buf, buf.length, address, sendPort); + socket.send(packet); + } + + public void close() { + + socket.close(); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java new file mode 100644 index 000000000..7790fbee7 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java @@ -0,0 +1,124 @@ +package us.dot.its.jpo.ode.udp.map; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.json.JSONObject; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.context.EmbeddedKafka; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.model.OdeMsgMetadata; +import us.dot.its.jpo.ode.testUtilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.ServiceManager; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.udp.controller.UdpServiceThreadFactory; +import us.dot.its.jpo.ode.util.DateTimeUtils; +import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; + +import java.io.IOException; +import java.time.Clock; +import java.time.Instant; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; + +@Slf4j +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = {UDPReceiverProperties.class, OdeKafkaProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class}) +@RunWith(SpringRunner.class) +@DirtiesContext +@EmbeddedKafka(partitions = 1, topics = {"topic.OdeRawEncodedMAPJson"}, ports = 4242) +class MapReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + private EmbeddedKafkaBroker embeddedKafka; + + ServiceManager rm; + TestUDPClient udpClient; + MapReceiver mapReceiver; + + @BeforeEach + public void setUp() { + rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); + + mapReceiver = new MapReceiver(udpReceiverProperties.getMap(), + odeKafkaProperties, + rawEncodedJsonTopics.getMap()); + + // Set the clock to a fixed time so that the MapReceiver will produce the same output every time + DateTimeUtils.setClock(Clock.fixed(Instant.parse("2020-01-01T00:00:00Z"), Clock.systemUTC().getZone())); + // Set the static schema version to 7 so that the MapReceiver will produce the same output every time + // This is necessary because the schema version is set in only one of the OdeMsgMetadata constructors (this should be fixed) + // and the schema version is set to the static schema version in the constructor. This means that the schema version + // will be set to 6 for all OdeMsgMetadata objects created in the MapReceiver run method's code path. + OdeMsgMetadata.setStaticSchemaVersion(7); + } + + @AfterEach + public void tearDown() { + mapReceiver.setStopped(true); + udpClient.close(); + } + + @Test + void testMapReceiver() throws IOException { + String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json"; + List approvalTestCases = deserializeTestCases(path, "\u0000\u0012"); + + // Start the MapReceiver in a new thread + rm.submit(mapReceiver); + + // Set up a Kafka consumer + Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getMap()); + + udpClient = new TestUDPClient(udpReceiverProperties.getMap().getReceiverPort()); + + for (ApprovalTestCase approvalTestCase : approvalTestCases) { + udpClient.send(approvalTestCase.getInput()); + + ConsumerRecord produced = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getMap()); + + JSONObject producedJson = new JSONObject(produced.value()); + JSONObject expectedJson = new JSONObject(approvalTestCase.getExpected()); + // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals(expectedJson.toString(), producedJson.toString()); + } + } +} + diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/uper/UperUtilTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/uper/UperUtilTest.java index 0fa1c8909..dfb5e43f3 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/uper/UperUtilTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/uper/UperUtilTest.java @@ -1,21 +1,20 @@ package us.dot.its.jpo.ode.uper; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import java.util.HashMap; import org.apache.tomcat.util.buf.HexUtils; import org.junit.jupiter.api.Test; - import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; -public class UperUtilTest { - UperUtil testUperUtil; +import java.util.HashMap; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class UperUtilTest { @Test - public void testStripDot2Header() { + void testStripDot2Header() throws StartFlagNotFoundException { String testHexString = "10110014000000"; String testPayloadStartFlag = "0014"; String expectedValue = "001400"; @@ -23,17 +22,16 @@ public void testStripDot2Header() { } @Test - public void testStripDot2HeaderBadData() { + void testStripDot2HeaderBadData() { String testHexString = "0014"; String testPayloadStartFlag = "0015"; - String expectedValue = "BAD DATA"; - assertEquals(expectedValue, UperUtil.stripDot2Header(testHexString, testPayloadStartFlag)); + assertThrows(StartFlagNotFoundException.class, () -> UperUtil.stripDot2Header(testHexString, testPayloadStartFlag)); } @Test - public void testStripDot3Header() { - byte[] testPacket = { 0x10, 0x20, 0x00, 0x1f, 0x00, 0x00 }; - byte[] testExpected = { 0x00, 0x1f, 0x00 }; + void testStripDot3Header() { + byte[] testPacket = {0x10, 0x20, 0x00, 0x1f, 0x00, 0x00}; + byte[] testExpected = {0x00, 0x1f, 0x00}; HashMap testMsgStartFlag = new HashMap<>(); testMsgStartFlag.put("TIM", "001f"); byte[] testResult = UperUtil.stripDot3Header(testPacket, testMsgStartFlag); @@ -41,9 +39,9 @@ public void testStripDot3Header() { } @Test - public void testStripDot3HeaderWithDot2StartIndex() { - byte[] testPacket = { 0x0, 0x01, 0x03, (byte) 0x81, 0x00, 0x00, 0x1f, 0x00 }; - byte[] testExpected = { 0x03, (byte) 0x81, 0x00, 0x00, 0x1f, 0x00 }; + void testStripDot3HeaderWithDot2StartIndex() { + byte[] testPacket = {0x0, 0x01, 0x03, (byte) 0x81, 0x00, 0x00, 0x1f, 0x00}; + byte[] testExpected = {0x03, (byte) 0x81, 0x00, 0x00, 0x1f, 0x00}; HashMap testMsgStartFlag = new HashMap<>(); testMsgStartFlag.put("TIM", "001f"); byte[] testResult = UperUtil.stripDot3Header(testPacket, testMsgStartFlag); @@ -51,7 +49,7 @@ public void testStripDot3HeaderWithDot2StartIndex() { } @Test - public void testStripDot3HeaderString() { + void testStripDot3HeaderString() { String testPacketString = "0102001f0000"; String testExpectedString = "001f00"; String testMsgStartFlag = "001f"; @@ -59,7 +57,7 @@ public void testStripDot3HeaderString() { } @Test - public void testStripDot3HeaderStringWithDot2StartIndex() { + void testStripDot3HeaderStringWithDot2StartIndex() { String testPacketString = "0001038100001f00"; String testExpectedString = "038100001f00"; String testMsgStartFlag = "001f"; @@ -67,18 +65,18 @@ public void testStripDot3HeaderStringWithDot2StartIndex() { } @Test - public void testDetermineMessageType() throws JsonUtilsException { + void testDetermineMessageType() { String mapHexString = "0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; OdeAsn1Payload mapPayload = new OdeAsn1Payload(HexUtils.fromHexString(mapHexString)); - assertEquals(UperUtil.determineMessageType(mapPayload), "MAP"); + assertEquals("MAP", UperUtil.determineMessageType(mapPayload)); String timHexString = "001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; OdeAsn1Payload timPayload = new OdeAsn1Payload(HexUtils.fromHexString(timHexString)); - assertEquals(UperUtil.determineMessageType(timPayload), "TIM"); + assertEquals("TIM", UperUtil.determineMessageType(timPayload)); } @Test - public void testStripTrailingZeros() { + void testStripTrailingZeros() { // Test case: String with trailing zeros String input1 = "12340000"; String expected1 = "123400"; @@ -89,5 +87,4 @@ public void testStripTrailingZeros() { String expected2 = "12345000"; assertEquals(expected2, UperUtil.stripTrailingZeros(input2)); } - } diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml index 512cd14e0..90d61d6a8 100644 --- a/jpo-ode-svcs/src/test/resources/application.yaml +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -3,6 +3,20 @@ spring: multipart: max-file-size: 1MB max-request-size: 1MB + embedded: + kafka: + brokers: + property: localhost:9092 + kafka: + bootstrap-servers: localhost:9092 + producer: + key-serializer: org.apache.kafka.common.serialization.StringSerializer + value-serializer: org.apache.kafka.common.serialization.StringSerializer + consumer: + key-deserializer: org.apache.kafka.common.serialization.StringDeserializer + value-deserializer: org.apache.kafka.common.serialization.StringDeserializer + group-id: test-group + auto-offset-reset: earliest ode: output-schema-version: 7 security-services: @@ -16,7 +30,7 @@ ode: username: "test-username" password: "test-password" kafka: - brokers: "localhost:9092" + brokers: "localhost:4242" producer: type: "async" acks: "0" diff --git a/jpo-ode-svcs/src/test/resources/logback-test.xml b/jpo-ode-svcs/src/test/resources/logback-test.xml index a7a69c483..de2819295 100644 --- a/jpo-ode-svcs/src/test/resources/logback-test.xml +++ b/jpo-ode-svcs/src/test/resources/logback-test.xml @@ -1,10 +1,10 @@ - - - %msg%n - - - - - + + + %msg%n + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json new file mode 100644 index 000000000..b898afd59 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json @@ -0,0 +1,14099 @@ +{ + "cases": [ + { + "description": "Test Case 1 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadc2010d5f-9ee5-4fef-9242-640e8c17713910002024-11-08T22:01:13.148Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617440366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "c2010d5f-9ee5-4fef-9242-640e8c177139", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:01:13.148Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.30" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8802 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5948212, + "longitude": -104.8830946, + "elevation": "1744.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 22, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1355, + "y": -1880 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2926 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 167, + "y": -2318 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -167, + "y": -1910 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1428, + "y": -7986 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 23, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1004, + "y": -1955 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 544, + "y": -1765 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 311, + "y": -1853 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 121, + "y": -1549 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -1876 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1008, + "y": -5542 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -697, + "y": -3586 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 624, + "y": -2010 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2868 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 207, + "y": -2180 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -305, + "y": -2656 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1590, + "y": -8364 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2522, + "y": -1862 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -380, + "y": -981 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 518, + "y": -2926 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": -1371 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -161, + "y": -2019 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -677, + "y": -3426 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 28, + "ingressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1676, + "y": -3102 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1797, + "y": 608 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4401, + "y": -356 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9504, + "y": -23 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -7238, + "y": 39 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2171, + "y": -6 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1517, + "y": -2824 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1411, + "y": 614 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "egressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -6816, + "y": -10691 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 161 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "egressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -6597, + "y": -10387 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -207, + "y": 166 + } + } + } + ] + } + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -664, + "y": -799 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3525, + "y": -586 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2446, + "y": -225 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2350, + "y": -138 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8407, + "y": -18 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8513, + "y": 17 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 17, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -531, + "y": -1503 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2310, + "y": -419 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3646, + "y": -430 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10414, + "y": -143 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9909, + "y": 10 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -683, + "y": -1177 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3456, + "y": -562 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2411, + "y": -259 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10834, + "y": -138 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -9372, + "y": 39 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1538, + "y": -296 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 63 + } + } + } + ] + } + } + }, + { + "laneID": 18, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1619, + "y": -669 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 265, + "y": 92 + } + } + } + ] + } + } + }, + { + "laneID": 19, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1757, + "y": -1059 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 80 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 8, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2269, + "y": 1625 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -311, + "y": -57 + } + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2200, + "y": 1293 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -334, + "y": -63 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2108, + "y": 914 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -369, + "y": -57 + } + } + } + ] + } + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2056, + "y": 564 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -69 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1975, + "y": 197 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -374, + "y": -80 + } + } + } + ] + } + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1710, + "y": 2641 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -415, + "y": 2042 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 516 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1365, + "y": 2715 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -484, + "y": 2065 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -150, + "y": 528 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -587, + "y": 2813 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -69, + "y": 235 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 520, + "y": 2310 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3064, + "y": 643 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 5840, + "y": 889 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 356 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3329, + "y": 207 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 13, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 595, + "y": 1960 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4642, + "y": 895 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4953, + "y": 711 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 6117, + "y": 516 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 14, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 664, + "y": 1620 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3594, + "y": 677 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3577, + "y": 574 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 2427, + "y": 309 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2387, + "y": 246 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2442, + "y": 172 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 1210, + "y": 80 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 732, + "y": 1263 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5921, + "y": 1073 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 476 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2422, + "y": 240 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3631, + "y": 251 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 800, + "y": 894 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 683 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4735, + "y": 723 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 384 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3625, + "y": 249 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 8335, + "y": -222 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 23 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test Case 2 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadcfc309e0-bcf6-4834-9178-4600d4998b3710002024-11-08T22:01:11.230Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817230366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "cfc309e0-bcf6-4834-9178-4600d4998b37", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:01:11.230Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800", + "mapSource": "RSU", + "originIp": "10.11.81.33" + }, + "payload": { + "data": { + "msgIssueRevision": 3, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8805 + }, + "revision": 3, + "refPoint": { + "latitude": 39.5950548, + "longitude": -104.8667908, + "elevation": "1723.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1821, + "y": 1201 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22824, + "y": -17 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22927, + "y": -23 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1831, + "y": 833 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22791, + "y": -39 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22950, + "y": -6 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 18, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1839, + "y": 453 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22869, + "y": 8 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22893, + "y": -12 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2608, + "y": 71 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10503, + "y": 0 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2596, + "y": -288 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 9697, + "y": 6 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1815, + "y": 1527 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 16128, + "y": 38 + } + }, + "attributes": { + "dElevation": -90 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 21, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -844 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 461, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 22, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -1205 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 472, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1875, + "y": -1595 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 507, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 29, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -540, + "y": -2621 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -283 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -888, + "y": -2635 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -283 + } + } + } + ] + } + } + }, + { + "laneID": 31, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1300, + "y": -2685 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -248 + } + } + } + ] + } + } + }, + { + "laneID": 32, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2089, + "y": -1980 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -11230, + "y": 22 + } + }, + "attributes": { + "dElevation": 70 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 31, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2066, + "y": -1614 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -22451, + "y": -44 + } + }, + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22755, + "y": -14 + } + }, + "attributes": { + "dElevation": 70 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 23, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2041, + "y": -1320 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -22637, + "y": 29 + } + }, + "attributes": { + "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22601, + "y": 46 + } + }, + "attributes": { + "dElevation": 60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2030, + "y": -904 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22671, + "y": 3 + } + }, + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 18 + } + }, + "attributes": { + "dElevation": 60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 21, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 4, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2430, + "y": -107 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9878, + "y": -11 + } + }, + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2258, + "y": -556 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1939, + "y": 425 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -271, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1916, + "y": 792 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -300, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1910, + "y": 1154 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 8, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1899, + "y": 1504 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -594, + "y": 2467 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": 1503 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 2249 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -156, + "y": 2008 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -778, + "y": 2323 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1296, + "y": 2209 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1100, + "y": 1549 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -997, + "y": 2409 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 1767 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -105, + "y": 2959 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -153, + "y": 1231 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -420, + "y": 2100 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2123 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -674, + "y": 1331 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -755, + "y": 1210 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -835, + "y": 1061 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 3 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 2486 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": 3976 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 1922 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -599, + "y": 2473 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 12, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2509 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2467 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -58, + "y": 1979 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -242, + "y": 1916 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": 1618 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 21, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 442, + "y": 2545 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 333 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 851, + "y": 2533 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 338 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 25, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 974, + "y": -2408 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -60, + "y": -15160 + } + }, + "attributes": { + "dElevation": 50 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 26, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 564, + "y": -2467 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8, + "y": -15094 + } + }, + "attributes": { + "dElevation": 40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 202, + "y": -2492 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10, + "y": -15080 + } + }, + "attributes": { + "dElevation": 40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 28, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -148, + "y": -2541 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -3031 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2555, + "y": -2340 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -357, + "y": -252 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": -459 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": -562 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -177, + "y": -601 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -13, + "y": -9030 + } + }, + "attributes": { + "dElevation": 30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 3 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload894cf226-1c88-4e93-8a44-4e2e619593e310002024-11-08T22:01:11.974Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171403663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "894cf226-1c88-4e93-8a44-4e2e619593e3", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:01:11.974Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000", + "mapSource": "RSU", + "originIp": "10.11.81.36" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8808 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5950299, + "longitude": -104.8404171, + "elevation": "1714.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2287, + "y": -615 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22396, + "y": -4 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22917, + "y": 155 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2229, + "y": -954 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 43 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22850, + "y": 33 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2148, + "y": -1384 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22900, + "y": 37 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22584, + "y": 82 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 3 + } + ] + } + }, + { + "laneID": 4, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2431, + "y": 136 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -21380, + "y": 63 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1630, + "y": -321 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2534, + "y": 670 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2569, + "y": 1043 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -276, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2621, + "y": 1398 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -294, + "y": 11 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 8, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1486, + "y": 2087 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": 6379 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1158, + "y": 2075 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 63, + "y": 6402 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2052 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 69, + "y": 6425 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 2070 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 436 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 645, + "y": 2070 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 436 + } + } + } + ] + } + } + }, + { + "laneID": 13, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1947, + "y": 1325 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22150, + "y": -46 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22325, + "y": -85 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 3 + } + ] + } + }, + { + "laneID": 14, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2033, + "y": 1003 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22028, + "y": -42 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22360, + "y": -105 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2068, + "y": 624 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22029, + "y": -52 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22307, + "y": -72 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2125, + "y": 314 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 24076, + "y": -138 + } + }, + "attributes": { + "dElevation": 30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2183, + "y": -87 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 20228, + "y": -69 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 18, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2275, + "y": -661 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 282, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 19, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2344, + "y": -1068 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 20, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2385, + "y": -1395 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 22, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 697, + "y": -2067 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 6, + "y": -4044 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -2123 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -104, + "y": -929 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -518, + "y": -2708 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1140, + "y": -4991 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1089, + "y": -2072 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": -1973 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -17, + "y": -2593 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -184, + "y": -1824 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -253, + "y": -1744 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -1847 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1146, + "y": -4894 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -12, + "y": -2095 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": -4222 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 23, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 334, + "y": -2101 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": -4142 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -81, + "y": -1411 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -236, + "y": -2042 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": -2174 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1112, + "y": -4871 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -570, + "y": -2153 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -6, + "y": -293 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1043, + "y": -2153 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -281 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 3 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadd71ab23d-0f89-4847-abef-ea6ffe43995b10002024-11-08T22:01:12.973Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689036618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "d71ab23d-0f89-4847-abef-ea6ffe43995b", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:01:12.973Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200", + "mapSource": "RSU", + "originIp": "10.11.81.19" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 12113 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5662624, + "longitude": -105.0827211, + "elevation": "1689.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 18, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -161, + "y": 1679 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -14, + "y": 5804 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": -173, + "y": 2537 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 27, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -521, + "y": 1709 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 9274 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -219, + "y": 3765 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 28, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -840, + "y": 1704 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 10009 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 4867 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 218, + "y": 22016 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -115, + "y": 9779 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1234, + "y": 1718 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 7989 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3, + "y": 8106 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 78, + "y": 24524 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY5": { + "x": -161, + "y": 6037 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 511, + "y": 1577 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 17, + "y": 321 + } + } + } + ] + } + } + }, + { + "laneID": 20, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 926, + "y": 1583 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 12, + "y": 298 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1732, + "y": 866 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6892, + "y": -149 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5428, + "y": -195 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1718, + "y": 528 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3215, + "y": -17 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6091, + "y": -253 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3008, + "y": -57 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 10, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1770, + "y": 201 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 4477, + "y": -57 + } + } + }, + { + "delta": { + "nodeXY3": { + "x": 1965, + "y": -57 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 26, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1735, + "y": -126 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5584, + "y": -132 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 2507, + "y": 390 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "egressApproach": 12, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1646, + "y": -621 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 305, + "y": 11 + } + } + } + ] + } + } + }, + { + "laneID": 28, + "egressApproach": 12, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1623, + "y": -994 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 317, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "ingressApproach": 14, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1908, + "y": -1870 + } + } + }, + { + "delta": { + "nodeXY2": { + "x": -472, + "y": -953 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -102, + "y": -8773 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 234, + "y": -1688 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 35, + "y": -6680 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 53, + "y": -3539 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 10, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 578, + "y": -1677 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 69, + "y": -6709 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 43, + "y": -8790 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 40, + "y": -16478 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": -15152 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 950, + "y": -1698 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 63, + "y": -7180 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 12, + "y": -3639 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 40, + "y": -6124 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 103, + "y": -15105 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -46, + "y": -15037 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1823, + "y": -12 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -5157, + "y": 46 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2339, + "y": -339 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 8, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1817, + "y": -334 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6609, + "y": 29 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 7, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1850, + "y": -614 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6045, + "y": -23 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2288, + "y": 172 + } + } + }, + { + "delta": { + "nodeXY2": { + "x": -669, + "y": -5 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 27, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 6, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1856, + "y": -947 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -4644, + "y": -80 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": -3106, + "y": 168 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY3": { + "x": -1245, + "y": 23 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 28, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 10, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1829, + "y": 447 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -236, + "y": 6 + } + } + } + ] + } + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1788, + "y": 860 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 21, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1369, + "y": 9302 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 23, + "y": 505 + } + } + } + ] + } + } + }, + { + "laneID": 5, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1195, + "y": -1533 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": -29, + "y": -425 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -786, + "y": -1510 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": -23, + "y": -448 + } + } + } + ] + } + } + }, + { + "laneID": 29, + "egressApproach": 13, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": 5345, + "y": -1396 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 392, + "y": 17 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2133, + "y": 1785 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 484, + "y": 895 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 29, + "y": 6979 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 219, + "y": 5992 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -4894, + "y": 896 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -4883, + "y": 540 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": -6 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 4 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2c91e8d6-f917-4c82-96e4-9de0da3ddca710002024-11-08T22:01:11.319Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706901702036618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "2c91e8d6-f917-4c82-96e4-9de0da3ddca7", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:01:11.319Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.20" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 12112 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5806913, + "longitude": "-105.0870690", + "elevation": "1702.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 18, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2121, + "y": 1567 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -3670, + "y": 7970 + } + }, + "attributes": { + "dElevation": 50 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1195, + "y": 2499 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -1832, + "y": 4149 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4313, + "y": 9347 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4364, + "y": 9515 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4272, + "y": 9547 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1752, + "y": 1601 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2218, + "y": 4912 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2662, + "y": 5807 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2581, + "y": 5566 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3255, + "y": 7046 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -4489, + "y": 9829 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4488, + "y": 9976 + } + }, + "attributes": { + "dElevation": -50 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1313, + "y": 1627 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2022, + "y": 4378 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1194, + "y": 2575 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -813, + "y": 1649 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2201, + "y": 4447 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3289, + "y": 6358 + } + }, + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1930, + "y": 3753 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 22, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -191, + "y": 1636 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 333 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 212, + "y": 1688 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -121, + "y": 350 + } + } + } + ] + } + } + }, + { + "laneID": 24, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 684, + "y": 1751 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 298 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "ingressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 2022, + "y": 816 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2454, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3503, + "y": -172 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 7472, + "y": -293 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8019, + "y": -63 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3405, + "y": 115 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4747, + "y": 310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 2370, + "y": 498 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4419, + "y": -149 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 8497, + "y": -344 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3531, + "y": -34 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8106, + "y": 52 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4718, + "y": 316 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": true, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3423, + "y": 1969 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 236, + "y": 620 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": -262, + "y": 993 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2057, + "y": 4491 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY4": { + "x": -951, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 15, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 16, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 29, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 3219, + "y": -405 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 311, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 3211, + "y": -1006 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 409, + "y": 6 + } + } + } + ] + } + } + }, + { + "laneID": 31, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 2729, + "y": -1696 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY3": { + "x": 7, + "y": -1089 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2736, + "y": -6046 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY2": { + "x": 393, + "y": -951 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1012, + "y": -1671 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2845, + "y": -6288 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY3": { + "x": 904, + "y": -1899 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1430, + "y": -1698 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2767, + "y": -6178 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3194, + "y": -6835 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2990, + "y": -6513 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5135, + "y": -11024 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5003, + "y": -11021 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1840, + "y": -1673 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3318, + "y": -7339 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2599, + "y": -5381 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2407, + "y": -5583 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5425, + "y": -11583 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5441, + "y": -11713 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 23, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 7, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1081, + "y": -1540 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 127, + "y": -310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -649, + "y": -1528 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 104, + "y": -361 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 5, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -234, + "y": -1517 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 98, + "y": -333 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 238, + "y": -1545 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 92, + "y": -373 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 10, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2640, + "y": -253 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9828, + "y": -17 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10070, + "y": 57 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9788, + "y": -17 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2452, + "y": -630 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -14852, + "y": 46 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -15059, + "y": -11 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3066, + "y": 1034 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -305, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3054, + "y": 644 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": 0 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 16, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6475, + "y": 1452 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -409, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 15, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6515, + "y": 1096 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -369, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6521, + "y": 752 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -363, + "y": -6 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + } + ] +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json new file mode 100644 index 000000000..73ea4019f --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json @@ -0,0 +1,14099 @@ +{ + "cases": [ + { + "description": "Test Case 1 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload85100a89-9411-4bc3-828c-9c398aa829a510002024-11-08T21:38:24.144Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617440366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "85100a89-9411-4bc3-828c-9c398aa829a5", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:38:24.144Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.30" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8802 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5948212, + "longitude": -104.8830946, + "elevation": "1744.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 22, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1355, + "y": -1880 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2926 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 167, + "y": -2318 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -167, + "y": -1910 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1428, + "y": -7986 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 23, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1004, + "y": -1955 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 544, + "y": -1765 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 311, + "y": -1853 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 121, + "y": -1549 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -1876 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1008, + "y": -5542 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -697, + "y": -3586 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 624, + "y": -2010 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2868 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 207, + "y": -2180 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -305, + "y": -2656 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1590, + "y": -8364 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2522, + "y": -1862 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -380, + "y": -981 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 518, + "y": -2926 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": -1371 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -161, + "y": -2019 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -677, + "y": -3426 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 28, + "ingressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1676, + "y": -3102 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1797, + "y": 608 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4401, + "y": -356 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9504, + "y": -23 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -7238, + "y": 39 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2171, + "y": -6 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1517, + "y": -2824 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1411, + "y": 614 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "egressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -6816, + "y": -10691 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 161 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "egressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -6597, + "y": -10387 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -207, + "y": 166 + } + } + } + ] + } + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -664, + "y": -799 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3525, + "y": -586 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2446, + "y": -225 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2350, + "y": -138 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8407, + "y": -18 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8513, + "y": 17 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 17, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -531, + "y": -1503 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2310, + "y": -419 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3646, + "y": -430 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10414, + "y": -143 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9909, + "y": 10 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -683, + "y": -1177 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3456, + "y": -562 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2411, + "y": -259 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10834, + "y": -138 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -9372, + "y": 39 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1538, + "y": -296 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 63 + } + } + } + ] + } + } + }, + { + "laneID": 18, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1619, + "y": -669 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 265, + "y": 92 + } + } + } + ] + } + } + }, + { + "laneID": 19, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1757, + "y": -1059 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 80 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 8, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2269, + "y": 1625 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -311, + "y": -57 + } + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2200, + "y": 1293 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -334, + "y": -63 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2108, + "y": 914 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -369, + "y": -57 + } + } + } + ] + } + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2056, + "y": 564 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -69 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1975, + "y": 197 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -374, + "y": -80 + } + } + } + ] + } + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1710, + "y": 2641 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -415, + "y": 2042 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 516 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1365, + "y": 2715 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -484, + "y": 2065 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -150, + "y": 528 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -587, + "y": 2813 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -69, + "y": 235 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 520, + "y": 2310 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3064, + "y": 643 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 5840, + "y": 889 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 356 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3329, + "y": 207 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 13, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 595, + "y": 1960 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4642, + "y": 895 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4953, + "y": 711 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 6117, + "y": 516 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 14, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 664, + "y": 1620 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3594, + "y": 677 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3577, + "y": 574 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 2427, + "y": 309 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2387, + "y": 246 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2442, + "y": 172 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 1210, + "y": 80 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 732, + "y": 1263 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5921, + "y": 1073 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 476 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2422, + "y": 240 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3631, + "y": 251 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 800, + "y": 894 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 683 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4735, + "y": 723 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 384 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3625, + "y": 249 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 8335, + "y": -222 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 23 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test Case 2 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadffadc418-5fcd-43b7-b931-024edc375fae10002024-11-08T22:00:01.224Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817230366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "ffadc418-5fcd-43b7-b931-024edc375fae", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T22:00:01.224Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800", + "mapSource": "RSU", + "originIp": "10.11.81.33" + }, + "payload": { + "data": { + "msgIssueRevision": 3, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8805 + }, + "revision": 3, + "refPoint": { + "latitude": 39.5950548, + "longitude": -104.8667908, + "elevation": "1723.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1821, + "y": 1201 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22824, + "y": -17 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22927, + "y": -23 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1831, + "y": 833 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22791, + "y": -39 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22950, + "y": -6 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 18, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1839, + "y": 453 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 22869, + "y": 8 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22893, + "y": -12 + } + }, + "attributes": { + "dElevation": -40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2608, + "y": 71 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10503, + "y": 0 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2596, + "y": -288 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 9697, + "y": 6 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1815, + "y": 1527 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 16128, + "y": 38 + } + }, + "attributes": { + "dElevation": -90 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 21, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -844 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 461, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 22, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -1205 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 472, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1875, + "y": -1595 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 507, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 29, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -540, + "y": -2621 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -283 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -888, + "y": -2635 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -283 + } + } + } + ] + } + } + }, + { + "laneID": 31, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1300, + "y": -2685 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -248 + } + } + } + ] + } + } + }, + { + "laneID": 32, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2089, + "y": -1980 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -11230, + "y": 22 + } + }, + "attributes": { + "dElevation": 70 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 31, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2066, + "y": -1614 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -22451, + "y": -44 + } + }, + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22755, + "y": -14 + } + }, + "attributes": { + "dElevation": 70 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 23, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2041, + "y": -1320 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -22637, + "y": 29 + } + }, + "attributes": { + "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22601, + "y": 46 + } + }, + "attributes": { + "dElevation": 60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2030, + "y": -904 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22671, + "y": 3 + } + }, + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 18 + } + }, + "attributes": { + "dElevation": 60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 21, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 4, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2430, + "y": -107 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9878, + "y": -11 + } + }, + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2258, + "y": -556 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1939, + "y": 425 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -271, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1916, + "y": 792 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -300, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1910, + "y": 1154 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 8, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1899, + "y": 1504 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -594, + "y": 2467 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": 1503 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 2249 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -156, + "y": 2008 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -778, + "y": 2323 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1296, + "y": 2209 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1100, + "y": 1549 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -997, + "y": 2409 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 1767 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -105, + "y": 2959 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -153, + "y": 1231 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -420, + "y": 2100 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2123 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -674, + "y": 1331 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -755, + "y": 1210 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -835, + "y": 1061 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 8, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 3 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 2486 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": 3976 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 1922 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -599, + "y": 2473 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 12, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2509 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2467 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -58, + "y": 1979 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -242, + "y": 1916 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": 1618 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 21, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 442, + "y": 2545 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 333 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 851, + "y": 2533 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 338 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 25, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 974, + "y": -2408 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -60, + "y": -15160 + } + }, + "attributes": { + "dElevation": 50 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 26, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 564, + "y": -2467 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8, + "y": -15094 + } + }, + "attributes": { + "dElevation": 40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 202, + "y": -2492 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10, + "y": -15080 + } + }, + "attributes": { + "dElevation": 40 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 28, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -148, + "y": -2541 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -3031 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2555, + "y": -2340 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -357, + "y": -252 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": -459 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": -562 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -177, + "y": -601 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -13, + "y": -9030 + } + }, + "attributes": { + "dElevation": 30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 3 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload6ef718b4-ad04-4260-a9f2-f8c596f0019310002024-11-08T21:52:36.968Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171403663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "6ef718b4-ad04-4260-a9f2-f8c596f00193", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:52:36.968Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000", + "mapSource": "RSU", + "originIp": "10.11.81.36" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 8808 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5950299, + "longitude": -104.8404171, + "elevation": "1714.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2287, + "y": -615 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22396, + "y": -4 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22917, + "y": 155 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2229, + "y": -954 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 43 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22850, + "y": 33 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2148, + "y": -1384 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22900, + "y": 37 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22584, + "y": 82 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 3 + } + ] + } + }, + { + "laneID": 4, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2431, + "y": 136 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -21380, + "y": 63 + } + }, + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1630, + "y": -321 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 5, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2534, + "y": 670 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2569, + "y": 1043 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -276, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 7, + "egressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -2621, + "y": 1398 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -294, + "y": 11 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + } + }, + { + "laneID": 8, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1486, + "y": 2087 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": 6379 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1158, + "y": 2075 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 63, + "y": 6402 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 10, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2052 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 69, + "y": 6425 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 18, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 2070 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 436 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 645, + "y": 2070 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 436 + } + } + } + ] + } + } + }, + { + "laneID": 13, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1947, + "y": 1325 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22150, + "y": -46 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22325, + "y": -85 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 7, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 3 + } + ] + } + }, + { + "laneID": 14, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2033, + "y": 1003 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22028, + "y": -42 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22360, + "y": -105 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2068, + "y": 624 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22029, + "y": -52 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22307, + "y": -72 + } + }, + "attributes": { + "dElevation": 80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2125, + "y": 314 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 24076, + "y": -138 + } + }, + "attributes": { + "dElevation": 30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 26, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2183, + "y": -87 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 20228, + "y": -69 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 25, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 18, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2275, + "y": -661 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 282, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 19, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2344, + "y": -1068 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": -6 + } + } + } + ] + } + } + }, + { + "laneID": 20, + "egressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 2385, + "y": -1395 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 22, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 697, + "y": -2067 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 6, + "y": -4044 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -2123 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -104, + "y": -929 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -518, + "y": -2708 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1140, + "y": -4991 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1089, + "y": -2072 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": -1973 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -17, + "y": -2593 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -184, + "y": -1824 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -253, + "y": -1744 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -1847 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1146, + "y": -4894 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": true, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -12, + "y": -2095 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": -4222 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": true, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 23, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 334, + "y": -2101 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": -4142 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -81, + "y": -1411 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -236, + "y": -2042 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": -2174 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1112, + "y": -4871 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -570, + "y": -2153 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -6, + "y": -293 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": -1043, + "y": -2153 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -281 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 3 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload3cfe36c5-8cbc-43f3-af8f-a148520df6d910002024-11-08T21:52:39.971Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689036618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "3cfe36c5-8cbc-43f3-af8f-a148520df6d9", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:52:39.971Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200", + "mapSource": "RSU", + "originIp": "10.11.81.19" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 12113 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5662624, + "longitude": -105.0827211, + "elevation": "1689.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 18, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -161, + "y": 1679 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -14, + "y": 5804 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": -173, + "y": 2537 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 27, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -521, + "y": 1709 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 9274 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -219, + "y": 3765 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 28, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 16, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -840, + "y": 1704 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 10009 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 4867 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 218, + "y": 22016 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -115, + "y": 9779 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 15, + "ingressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1234, + "y": 1718 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 7989 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3, + "y": 8106 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 78, + "y": 24524 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY5": { + "x": -161, + "y": 6037 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 511, + "y": 1577 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 17, + "y": 321 + } + } + } + ] + } + } + }, + { + "laneID": 20, + "egressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 926, + "y": 1583 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 12, + "y": 298 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1732, + "y": 866 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6892, + "y": -149 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5428, + "y": -195 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 24, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1718, + "y": 528 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3215, + "y": -17 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6091, + "y": -253 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3008, + "y": -57 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 10, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 25, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1770, + "y": 201 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 4477, + "y": -57 + } + } + }, + { + "delta": { + "nodeXY3": { + "x": 1965, + "y": -57 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 26, + "ingressApproach": 11, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1735, + "y": -126 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5584, + "y": -132 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 2507, + "y": 390 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 4, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 3, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "egressApproach": 12, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1646, + "y": -621 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 305, + "y": 11 + } + } + } + ] + } + } + }, + { + "laneID": 28, + "egressApproach": 12, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1623, + "y": -994 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 317, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "ingressApproach": 14, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1908, + "y": -1870 + } + } + }, + { + "delta": { + "nodeXY2": { + "x": -472, + "y": -953 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -102, + "y": -8773 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 234, + "y": -1688 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 35, + "y": -6680 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 53, + "y": -3539 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 10, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 11, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 578, + "y": -1677 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 69, + "y": -6709 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 43, + "y": -8790 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 40, + "y": -16478 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": -15152 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 950, + "y": -1698 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 63, + "y": -7180 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 12, + "y": -3639 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 40, + "y": -6124 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 103, + "y": -15105 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -46, + "y": -15037 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1823, + "y": -12 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -5157, + "y": 46 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2339, + "y": -339 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 19, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 8, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1817, + "y": -334 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6609, + "y": 29 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 20, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 7, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 7, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1850, + "y": -614 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6045, + "y": -23 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2288, + "y": 172 + } + } + }, + { + "delta": { + "nodeXY2": { + "x": -669, + "y": -5 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 27, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 6, + "ingressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1856, + "y": -947 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -4644, + "y": -80 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": -3106, + "y": 168 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY3": { + "x": -1245, + "y": 23 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 28, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 10, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1829, + "y": 447 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -236, + "y": 6 + } + } + } + ] + } + } + }, + { + "laneID": 11, + "egressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1788, + "y": 860 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 21, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY6": { + "x": 1369, + "y": 9302 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 23, + "y": 505 + } + } + } + ] + } + } + }, + { + "laneID": 5, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1195, + "y": -1533 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": -29, + "y": -425 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -786, + "y": -1510 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": -23, + "y": -448 + } + } + } + ] + } + } + }, + { + "laneID": 29, + "egressApproach": 13, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": 5345, + "y": -1396 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 392, + "y": 17 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2133, + "y": 1785 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 484, + "y": 895 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 29, + "y": 6979 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 219, + "y": 5992 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -4894, + "y": 896 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -4883, + "y": 540 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": -6 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + }, + { + "description": "Test case 4 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2af41559-45b0-48e8-95b4-a2d1368e2bf710002024-11-08T21:52:39.315Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706901702036618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", + "expected": { + "metadata": { + "logFileName": "", + "recordType": "mapTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "rxSource": "NA" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", + "serialId": { + "streamId": "2af41559-45b0-48e8-95b4-a2d1368e2bf7", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:52:39.315Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "RSU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.20" + }, + "payload": { + "data": { + "msgIssueRevision": 2, + "layerType": "intersectionData", + "layerID": 0, + "intersections": { + "intersectionGeometry": [ + { + "id": { + "id": 12112 + }, + "revision": 2, + "refPoint": { + "latitude": 39.5806913, + "longitude": "-105.0870690", + "elevation": "1702.0" + }, + "laneWidth": 366, + "laneSet": { + "GenericLane": [ + { + "laneID": 18, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2121, + "y": 1567 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -3670, + "y": 7970 + } + }, + "attributes": { + "dElevation": 50 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1195, + "y": 2499 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -1832, + "y": 4149 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4313, + "y": 9347 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4364, + "y": 9515 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4272, + "y": 9547 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 6, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 19, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1752, + "y": 1601 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2218, + "y": 4912 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2662, + "y": 5807 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2581, + "y": 5566 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3255, + "y": 7046 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -4489, + "y": 9829 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4488, + "y": 9976 + } + }, + "attributes": { + "dElevation": -50 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 5, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 6, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 20, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1313, + "y": 1627 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2022, + "y": 4378 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1194, + "y": 2575 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 21, + "ingressApproach": 2, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -813, + "y": 1649 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2201, + "y": 4447 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3289, + "y": 6358 + } + }, + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1930, + "y": 3753 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 1, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 22, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -191, + "y": 1636 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 333 + } + } + } + ] + } + } + }, + { + "laneID": 23, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 212, + "y": 1688 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -121, + "y": 350 + } + } + } + ] + } + } + }, + { + "laneID": 24, + "egressApproach": 3, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 684, + "y": 1751 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 298 + } + } + } + ] + } + } + }, + { + "laneID": 26, + "ingressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 2022, + "y": 816 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2454, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3503, + "y": -172 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 7472, + "y": -293 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8019, + "y": -63 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3405, + "y": 115 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4747, + "y": 310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 27, + "ingressApproach": 4, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 2370, + "y": 498 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4419, + "y": -149 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 8497, + "y": -344 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3531, + "y": -34 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8106, + "y": 52 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4718, + "y": 316 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 8, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 17, + "ingressApproach": 1, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": true, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3423, + "y": 1969 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 236, + "y": 620 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": -262, + "y": 993 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2057, + "y": 4491 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY4": { + "x": -951, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 14, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 15, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + }, + { + "connectingLane": { + "lane": 16, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + } + } + ] + } + }, + { + "laneID": 29, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 3219, + "y": -405 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 311, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 30, + "egressApproach": 5, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 3211, + "y": -1006 + } + } + }, + { + "delta": { + "nodeXY1": { + "x": 409, + "y": 6 + } + } + } + ] + } + } + }, + { + "laneID": 31, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": 2729, + "y": -1696 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY3": { + "x": 7, + "y": -1089 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2736, + "y": -6046 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY2": { + "x": 393, + "y": -951 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": true, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 3, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1012, + "y": -1671 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2845, + "y": -6288 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY3": { + "x": 904, + "y": -1899 + } + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 13, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 1 + }, + { + "connectingLane": { + "lane": 12, + "maneuver": { + "maneuverStraightAllowed": false, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": true, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 5, + "connectionID": 2 + } + ] + } + }, + { + "laneID": 2, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1430, + "y": -1698 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2767, + "y": -6178 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3194, + "y": -6835 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2990, + "y": -6513 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5135, + "y": -11024 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5003, + "y": -11021 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 22, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 1, + "ingressApproach": 6, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 1840, + "y": -1673 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3318, + "y": -7339 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2599, + "y": -5381 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2407, + "y": -5583 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5425, + "y": -11583 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5441, + "y": -11713 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 23, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 2, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 7, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -1081, + "y": -1540 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 127, + "y": -310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 6, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -649, + "y": -1528 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 104, + "y": -361 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 5, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": -234, + "y": -1517 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 98, + "y": -333 + } + } + } + ] + } + } + }, + { + "laneID": 4, + "egressApproach": 7, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY3": { + "x": 238, + "y": -1545 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 92, + "y": -373 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 10, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2640, + "y": -253 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9828, + "y": -17 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10070, + "y": 57 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9788, + "y": -17 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 29, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 9, + "ingressApproach": 8, + "laneAttributes": { + "directionalUse": { + "ingressPath": true, + "egressPath": false + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "maneuvers": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -2452, + "y": -630 + } + }, + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -14852, + "y": 46 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -15059, + "y": -11 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] + } + }, + "connectsTo": { + "connectsTo": [ + { + "connectingLane": { + "lane": 30, + "maneuver": { + "maneuverStraightAllowed": true, + "maneuverNoStoppingAllowed": false, + "goWithHalt": false, + "maneuverLeftAllowed": false, + "maneuverUTurnAllowed": false, + "maneuverLeftTurnOnRedAllowed": false, + "reserved1": false, + "maneuverRightAllowed": false, + "maneuverLaneChangeAllowed": false, + "yieldAllwaysRequired": false, + "maneuverRightTurnOnRedAllowed": false, + "caution": false + } + }, + "signalGroup": 4, + "connectionID": 1 + } + ] + } + }, + { + "laneID": 13, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3066, + "y": 1034 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -305, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 12, + "egressApproach": 9, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY4": { + "x": -3054, + "y": 644 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": 0 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] + } + } + }, + { + "laneID": 16, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6475, + "y": 1452 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -409, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 15, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6515, + "y": 1096 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -369, + "y": 0 + } + } + } + ] + } + } + }, + { + "laneID": 14, + "egressApproach": 10, + "laneAttributes": { + "directionalUse": { + "ingressPath": false, + "egressPath": true + }, + "shareWith": { + "busVehicleTraffic": false, + "trackedVehicleTraffic": false, + "individualMotorizedVehicleTraffic": false, + "taxiVehicleTraffic": false, + "overlappingLaneDescriptionProvided": false, + "cyclistVehicleTraffic": false, + "otherNonMotorizedTrafficTypes": false, + "multipleLanesTreatedAsOneLane": false, + "pedestrianTraffic": false, + "pedestriansTraffic": false + }, + "laneType": { + "vehicle": { + "isVehicleRevocableLane": false, + "isVehicleFlyOverLane": false, + "permissionOnRequest": false, + "hasIRbeaconCoverage": false, + "restrictedToBusUse": false, + "restrictedToTaxiUse": false, + "restrictedFromPublicUse": false, + "hovLaneUseOnly": false + } + } + }, + "nodeList": { + "nodes": { + "NodeXY": [ + { + "delta": { + "nodeXY5": { + "x": -6521, + "y": 752 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -363, + "y": -6 + } + } + } + ] + } + } + } + ] + } + } + ] + } + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP" + } + } + } + ] +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json new file mode 100644 index 000000000..0f5bacbdc --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json @@ -0,0 +1,164 @@ +{ + "cases": [ + { + "description": "Test case 1", + "input": { + "metadata": { + "recordType": "mapTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "e99b160c-b2b2-4282-85bd-02fafbc52417", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:46:51.146Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.30" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000" + } + } + }, + "expected": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloade99b160c-b2b2-4282-85bd-02fafbc5241710002024-11-08T21:46:51.146Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30us.dot.its.jpo.ode.model.OdeHexByteArray001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000" + }, + { + "description": "Test case 2", + "input": { + "metadata": { + "recordType": "mapTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "7afc0062-4747-4c45-9062-3e525e6d286c", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:46:50.228Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800", + "mapSource": "RSU", + "originIp": "10.11.81.33" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800" + } + } + }, + "expected": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload7afc0062-4747-4c45-9062-3e525e6d286c10002024-11-08T21:46:50.228Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33us.dot.its.jpo.ode.model.OdeHexByteArray001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800" + }, + { + "description": "Test case 3", + "input": { + "metadata": { + "recordType": "mapTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "91194b7c-ba02-4e71-8297-e11c2a968e62", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:46:50.967Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000", + "mapSource": "RSU", + "originIp": "10.11.81.36" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000" + } + } + }, + "expected": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload91194b7c-ba02-4e71-8297-e11c2a968e6210002024-11-08T21:46:50.967Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36us.dot.its.jpo.ode.model.OdeHexByteArray00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000" + }, + { + "description": "Test case 4", + "input": { + "metadata": { + "recordType": "mapTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "ce610ea5-0963-4c9e-a149-fc3c5b420d46", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:46:51.971Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200", + "mapSource": "RSU", + "originIp": "10.11.81.19" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200" + } + } + }, + "expected": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadce610ea5-0963-4c9e-a149-fc3c5b420d4610002024-11-08T21:46:51.971Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19us.dot.its.jpo.ode.model.OdeHexByteArray0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200" + }, + { + "description": "Test case 5", + "input": { + "metadata": { + "recordType": "mapTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "c8fbfede-ea1f-47d8-a039-0f0151468160", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-08T21:46:50.313Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "mapSource": "RSU", + "originIp": "10.11.81.20" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000" + } + } + }, + "expected": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadc8fbfede-ea1f-47d8-a039-0f015146816010002024-11-08T21:46:50.313Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20us.dot.its.jpo.ode.model.OdeHexByteArray0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000" + } + ] +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json new file mode 100644 index 000000000..f9d965ce8 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json @@ -0,0 +1,68 @@ +{ + "cases": [ + { + "description": "Valid MAP", + "input": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", + "expected": { + "metadata": { + "securityResultCode": "success", + "recordGeneratedBy": "RSU", + "schemaVersion": 7, + "mapSource": "RSU", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "recordId": 0, + "serialNumber": 0, + "streamId": "9a79753a-21f5-453f-8c0b-bf59a1b63285", + "bundleSize": 1, + "bundleId": 0 + }, + "sanitized": false, + "recordType": "mapTx", + "asn1": "0012303031323833423033383032333030303230343443343039344433453939423432434335454531443534323030324443333635383244323830303030303730303031423631353244453241303041304136433138444241343930313431344438304137373646323032383531414645423246313134303530353335453942313833333830413134323538333230303034303041343245303030323032323634303035383246323830303030303230303032393630464231453137354230343430463233363035303533363034444445333043304131343643303343424346393831343134443746353337384143303238323941463832304434423430353041333546353144433746383039463630353832413030303138303936304334413030303030303830303036353832373037383236364331384442413636303134323844383043463737374330323835314146443945454234303035304131354537323937443530313630383830303036303235383242303830303030303130303032333632373639453245383041304132424634323345313542363038313944323438304131343643303131424435323831343134443746354637383144303238323941464142364535334330353035303043353038303030344230373239303030303030323030303436424342413339463130313432384437384642383236303032374439414444394546443338303446313335364238314646413430413041324231444434303133393544453135464645383036333434303030323538333734383030303030313030303033354538344444334530304130413242443345433133333030433634383030303434303636433830303030303030364232423032423145383134313435374633433830413131303141423230303030303030314143433736414544413035303531354643433630323938423030433530303030303038303030343242454234334537304235433845444636443830394636324242333933463846423544423439464444383039463636414639344246463730313431343535454246383031313035383843303030313030393630303841303030303031303030303635374445443741323136424237443346324538313431344437314332374535323032374231414145413446454532303530353335363532453030323830394636303538394330303031303039363031304130303030303130303030363537443535374236373242393430334545373335444135354642463430394636324141443733464242313536443932303039433136323530303030343032323032324334303030303030303136313830394642363042303146423030374532303234433430303030303030313631393444463538434230323133303042383230323643343030303030303031363142373545463735423031464230304130303530353038303431313030303030303030443737323338363539303237423041464439324646384532303045343430303030303030333544444132313433343039454332424635393346453038383033313130303030303030304437374334383339323032374230414644314546463845323030413434303030303030303335444645323038443030394543324246344142464444383830323131303030303030303044373834393830433530323742304146443134464636303538313236383030303030313030303042354535344132393434303945433242463330433346443135464239413038313035363130343030303830324230373230303034303232433041333430303030303038303030354146353537313533363034464233354638373232303434303946363242464235343130383032433138383030313030383430324430383030303030303036424544414335374538313345433537464242383045423243304335343030303030323830303044423034313131323043303446423136324645323041304442324441313036463230353035313633374645303539314231413033303139453035303530414332323030303138303432313634303035383141413830303030303430303031333630393445314541303039463632433931313431424642363444363630423143304130413643424632433130323031343134304230373830303036303132433045353430303030303230303031354230353331304341383034464231363338324130413935423142463330343743303530353136323545453034443442313241373031454335383938413830414336433235443430323830313431343042303638303030363031324330463534303030303032303030304442303542393039444530344642333635433836313043343041304132433731304330454531363235444130334331423143354630314636303530353032433136303030313830344230343135303030303030383030303332433139303431424631363337464530414143423234464630354136353845323138313830364337313443303743383134313430423034383030303630313130313437323030303030303031423431314546453434303530353136303343413030354330303000", + "maxDurationTime": 0, + "odeReceivedAt": "2020-01-01T00:00:00.000Z", + "originIp": "127.0.0.1" + }, + "payload": { + "data": { + "bytes": "0012303031323833423033383032333030303230343443343039344433453939423432434335454531443534323030324443333635383244323830303030303730303031423631353244453241303041304136433138444241343930313431344438304137373646323032383531414645423246313134303530353335453942313833333830413134323538333230303034303041343245303030323032323634303035383246323830303030303230303032393630464231453137354230343430463233363035303533363034444445333043304131343643303343424346393831343134443746353337384143303238323941463832304434423430353041333546353144433746383039463630353832413030303138303936304334413030303030303830303036353832373037383236364331384442413636303134323844383043463737374330323835314146443945454234303035304131354537323937443530313630383830303036303235383242303830303030303130303032333632373639453245383041304132424634323345313542363038313944323438304131343643303131424435323831343134443746354637383144303238323941464142364535334330353035303043353038303030344230373239303030303030323030303436424342413339463130313432384437384642383236303032374439414444394546443338303446313335364238314646413430413041324231444434303133393544453135464645383036333434303030323538333734383030303030313030303033354538344444334530304130413242443345433133333030433634383030303434303636433830303030303030364232423032423145383134313435374633433830413131303141423230303030303030314143433736414544413035303531354643433630323938423030433530303030303038303030343242454234334537304235433845444636443830394636324242333933463846423544423439464444383039463636414639344246463730313431343535454246383031313035383843303030313030393630303841303030303031303030303635374445443741323136424237443346324538313431344437314332374535323032374231414145413446454532303530353335363532453030323830394636303538394330303031303039363031304130303030303130303030363537443535374236373242393430334545373335444135354642463430394636324141443733464242313536443932303039433136323530303030343032323032324334303030303030303136313830394642363042303146423030374532303234433430303030303030313631393444463538434230323133303042383230323643343030303030303031363142373545463735423031464230304130303530353038303431313030303030303030443737323338363539303237423041464439324646384532303045343430303030303030333544444132313433343039454332424635393346453038383033313130303030303030304437374334383339323032374230414644314546463845323030413434303030303030303335444645323038443030394543324246344142464444383830323131303030303030303044373834393830433530323742304146443134464636303538313236383030303030313030303042354535344132393434303945433242463330433346443135464239413038313035363130343030303830324230373230303034303232433041333430303030303038303030354146353537313533363034464233354638373232303434303946363242464235343130383032433138383030313030383430324430383030303030303036424544414335374538313345433537464242383045423243304335343030303030323830303044423034313131323043303446423136324645323041304442324441313036463230353035313633374645303539314231413033303139453035303530414332323030303138303432313634303035383141413830303030303430303031333630393445314541303039463632433931313431424642363444363630423143304130413643424632433130323031343134304230373830303036303132433045353430303030303230303031354230353331304341383034464231363338324130413935423142463330343743303530353136323545453034443442313241373031454335383938413830414336433235443430323830313431343042303638303030363031324330463534303030303032303030304442303542393039444530344642333635433836313043343041304132433731304330454531363235444130334331423143354630314636303530353032433136303030313830344230343135303030303030383030303332433139303431424631363337464530414143423234464630354136353845323138313830364337313443303743383134313430423034383030303630313130313437323030303030303031423431314546453434303530353136303343413030354330303000" + }, + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray" + } + } + }, + { + "description": "Valid MAP message - minimum allowed data elements", + "input": "00127b226d65746164617461223a7b227365637572697479526573756c74436f6465223a2273756363657373222c227265636f726447656e6572617465644279223a6e756c6c2c22736368656d6156657273696f6e223a362c226f64655061636b65744944223a22222c2273616e6974697a6564223a66616c73652c227265636f726454797065223a226d61705478222c22656e636f64696e6773223a6e756c6c2c227265636f726447656e6572617465644174223a22222c226d61784475726174696f6e54696d65223a302c226f646554696d53746172744461746554696d65223a22222c2272656365697665644d65737361676544657461696c73223a7b226c6f636174696f6e44617461223a6e756c6c2c227278536f75726365223a224e41227d2c226d6170536f75726365223a22525355222c227061796c6f616454797065223a2275732e646f742e6974732e6a706f2e6f64652e6d6f64656c2e4f64654d61705061796c6f6164222c2273657269616c4964223a7b227265636f72644964223a302c2273657269616c4e756d626572223a302c2273747265616d4964223a2231333962613361662d653530312d343835342d393332372d623965316132656438646662222c2262756e646c6553697a65223a312c2262756e646c654964223a307d2c226c6f6746696c654e616d65223a22222c226f646552656365697665644174223a224049534f5f444154455f54494d4540222c226f726967696e4970223a2231302e31312e38312e3132227d2c227061796c6f6164223a7b2264617461223a7b2274696d655374616d70223a6e756c6c2c226c6179657254797065223a22696e74657273656374696f6e44617461222c226c617965724944223a302c227265737472696374696f6e4c697374223a6e756c6c2c2264617461506172616d6574657273223a6e756c6c2c226d736749737375655265766973696f6e223a322c22696e74657273656374696f6e73223a7b22696e74657273656374696f6e47656f6d65747279223a5b7b2273706565644c696d697473223a6e756c6c2c226c616e65536574223a7b2247656e657269634c616e65223a5b7b22636f6e6e65637473546f223a7b22636f6e6e65637473546f223a5b7b2275736572436c617373223a6e756c6c2c22636f6e6e656374696f6e4944223a312c2272656d6f7465496e74657273656374696f6e223a6e756c6c2c227369676e616c47726f7570223a322c22636f6e6e656374696e674c616e65223a7b226c616e65223a31352c226d616e6575766572223a7b226d616e65757665725374726169676874416c6c6f776564223a747275652c226d616e65757665724e6f53746f7070696e67416c6c6f776564223a66616c73652c22676f5769746848616c74223a66616c73652c226d616e65757665724c656674416c6c6f776564223a66616c73652c226d616e6575766572555475726e416c6c6f776564223a66616c73652c226d616e65757665724c6566745475726e4f6e526564416c6c6f776564223a66616c73652c22726573657276656431223a66616c73652c226d616e65757665725269676874416c6c6f776564223a66616c73652c226d616e65757665724c616e654368616e6765416c6c6f776564223a66616c73652c227969656c64416c6c776179735265717569726564223a66616c73652c226d616e657576657252696768745475726e4f6e526564416c6c6f776564223a66616c73652c2263617574696f6e223a66616c73657d7d7d5d7d2c226c616e654944223a312c22656772657373417070726f616368223a6e756c6c2c226c616e6541747472696275746573223a7b22646972656374696f6e616c557365223a7b22696e677265737350617468223a747275652c2265677265737350617468223a66616c73657d2c22736861726557697468223a7b2262757356656869636c6554726166666963223a66616c73652c22747261636b656456656869636c6554726166666963223a66616c73652c22696e646976696475616c4d6f746f72697a656456656869636c6554726166666963223a66616c73652c227461786956656869636c6554726166666963223a66616c73652c226f7665726c617070696e674c616e654465736372697074696f6e50726f7669646564223a66616c73652c226379636c69737456656869636c6554726166666963223a66616c73652c226f746865724e6f6e4d6f746f72697a6564547261666669635479706573223a66616c73652c226d756c7469706c654c616e65735472656174656441734f6e654c616e65223a66616c73652c227065646573747269616e54726166666963223a66616c73652c227065646573747269616e7354726166666963223a66616c73657d2c226c616e6554797065223a7b227369646577616c6b223a6e756c6c2c227061726b696e67223a6e756c6c2c2263726f737377616c6b223a6e756c6c2c226d656469616e223a6e756c6c2c227374726970696e67223a6e756c6c2c2262696b654c616e65223a6e756c6c2c22747261636b656456656869636c65223a6e756c6c2c2276656869636c65223a7b22697356656869636c655265766f6361626c654c616e65223a66616c73652c22697356656869636c65466c794f7665724c616e65223a66616c73652c227065726d697373696f6e4f6e52657175657374223a66616c73652c226861734952626561636f6e436f766572616765223a66616c73652c2272657374726963746564546f427573557365223a66616c73652c2272657374726963746564546f54617869557365223a66616c73652c", + "expected": { + "metadata": { + "securityResultCode": "success", + "recordGeneratedBy": "RSU", + "schemaVersion": 7, + "mapSource": "RSU", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "recordId": 0, + "serialNumber": 0, + "streamId": "f085a371-082c-43ae-8c2a-044820b5f816", + "bundleSize": 1, + "bundleId": 0 + }, + "sanitized": false, + "recordType": "mapTx", + "asn1": "001230303132376232323664363537343631363436313734363132323361376232323733363536333735373236393734373935323635373337353663373434333666363436353232336132323733373536333633363537333733323232633232373236353633366637323634343736353665363537323631373436353634343237393232336136653735366336633263323237333633363836353664363135363635373237333639366636653232336133363263323236663634363535303631363336623635373434393434323233613232323232633232373336313665363937343639376136353634323233613636363136633733363532633232373236353633366637323634353437393730363532323361323236643631373035343738323232633232363536653633366636343639366536373733323233613665373536633663326332323732363536333666373236343437363536653635373236313734363536343431373432323361323232323263323236643631373834343735373236313734363936663665353436393664363532323361333032633232366636343635353436393664353337343631373237343434363137343635353436393664363532323361323232323263323237323635363336353639373636353634346436353733373336313637363534343635373436313639366337333232336137623232366336663633363137343639366636653434363137343631323233613665373536633663326332323732373835333666373537323633363532323361323234653431323237643263323236643631373035333666373537323633363532323361323235323533353532323263323237303631373936633666363136343534373937303635323233613232373537333265363436663734326536393734373332653661373036663265366636343635326536643666363436353663326534663634363534643631373035303631373936633666363136343232326332323733363537323639363136633439363432323361376232323732363536333666373236343439363432323361333032633232373336353732363936313663346537353664363236353732323233613330326332323733373437323635363136643439363432323361323233313333333936323631333336313636326436353335333033313264333433383335333432643339333333323337326436323339363533313631333236353634333836343636363232323263323236323735366536343663363535333639376136353232336133313263323236323735366536343663363534393634323233613330376432633232366336663637343636393663363534653631366436353232336132323232326332323666363436353532363536333635363937363635363434313734323233613232343034393533346635663434343135343435356635343439346434353430323232633232366637323639363736393665343937303232336132323331333032653331333132653338333132653331333232323764326332323730363137393663366636313634323233613762323236343631373436313232336137623232373436393664363535333734363136643730323233613665373536633663326332323663363137393635373235343739373036353232336132323639366537343635373237333635363337343639366636653434363137343631323232633232366336313739363537323439343432323361333032633232373236353733373437323639363337343639366636653463363937333734323233613665373536633663326332323634363137343631353036313732363136643635373436353732373332323361366537353663366332633232366437333637343937333733373536353532363537363639373336393666366532323361333232633232363936653734363537323733363536333734363936663665373332323361376232323639366537343635373237333635363337343639366636653437363536663664363537343732373932323361356237623232373337303635363536343463363936643639373437333232336136653735366336633263323236633631366536353533363537343232336137623232343736353665363537323639363334633631366536353232336135623762323236333666366536653635363337343733353436663232336137623232363336663665366536353633373437333534366632323361356237623232373537333635373234333663363137333733323233613665373536633663326332323633366636653665363536333734363936663665343934343232336133313263323237323635366436663734363534393665373436353732373336353633373436393666366532323361366537353663366332633232373336393637366536313663343737323666373537303232336133323263323236333666366536653635363337343639366536373463363136653635323233613762323236633631366536353232336133313335326332323664363136653635373537363635373232323361376232323664363136653635373537363635373235333734373236313639363736383734343136633663366637373635363432323361373437323735363532633232366436313665363537353736363537323465366635333734366637303730363936653637343136633663366637373635363432323361363636313663373336353263323236373666353736393734363834383631366337343232336136363631366300", + "maxDurationTime": 0, + "odeReceivedAt": "2020-01-01T00:00:00.000Z", + "originIp": "127.0.0.1" + }, + "payload": { + "data": { + "bytes": "001230303132376232323664363537343631363436313734363132323361376232323733363536333735373236393734373935323635373337353663373434333666363436353232336132323733373536333633363537333733323232633232373236353633366637323634343736353665363537323631373436353634343237393232336136653735366336633263323237333633363836353664363135363635373237333639366636653232336133363263323236663634363535303631363336623635373434393434323233613232323232633232373336313665363937343639376136353634323233613636363136633733363532633232373236353633366637323634353437393730363532323361323236643631373035343738323232633232363536653633366636343639366536373733323233613665373536633663326332323732363536333666373236343437363536653635373236313734363536343431373432323361323232323263323236643631373834343735373236313734363936663665353436393664363532323361333032633232366636343635353436393664353337343631373237343434363137343635353436393664363532323361323232323263323237323635363336353639373636353634346436353733373336313637363534343635373436313639366337333232336137623232366336663633363137343639366636653434363137343631323233613665373536633663326332323732373835333666373537323633363532323361323234653431323237643263323236643631373035333666373537323633363532323361323235323533353532323263323237303631373936633666363136343534373937303635323233613232373537333265363436663734326536393734373332653661373036663265366636343635326536643666363436353663326534663634363534643631373035303631373936633666363136343232326332323733363537323639363136633439363432323361376232323732363536333666373236343439363432323361333032633232373336353732363936313663346537353664363236353732323233613330326332323733373437323635363136643439363432323361323233313333333936323631333336313636326436353335333033313264333433383335333432643339333333323337326436323339363533313631333236353634333836343636363232323263323236323735366536343663363535333639376136353232336133313263323236323735366536343663363534393634323233613330376432633232366336663637343636393663363534653631366436353232336132323232326332323666363436353532363536333635363937363635363434313734323233613232343034393533346635663434343135343435356635343439346434353430323232633232366637323639363736393665343937303232336132323331333032653331333132653338333132653331333232323764326332323730363137393663366636313634323233613762323236343631373436313232336137623232373436393664363535333734363136643730323233613665373536633663326332323663363137393635373235343739373036353232336132323639366537343635373237333635363337343639366636653434363137343631323232633232366336313739363537323439343432323361333032633232373236353733373437323639363337343639366636653463363937333734323233613665373536633663326332323634363137343631353036313732363136643635373436353732373332323361366537353663366332633232366437333637343937333733373536353532363537363639373336393666366532323361333232633232363936653734363537323733363536333734363936663665373332323361376232323639366537343635373237333635363337343639366636653437363536663664363537343732373932323361356237623232373337303635363536343463363936643639373437333232336136653735366336633263323236633631366536353533363537343232336137623232343736353665363537323639363334633631366536353232336135623762323236333666366536653635363337343733353436663232336137623232363336663665366536353633373437333534366632323361356237623232373537333635373234333663363137333733323233613665373536633663326332323633366636653665363536333734363936663665343934343232336133313263323237323635366436663734363534393665373436353732373336353633373436393666366532323361366537353663366332633232373336393637366536313663343737323666373537303232336133323263323236333666366536653635363337343639366536373463363136653635323233613762323236633631366536353232336133313335326332323664363136653635373537363635373232323361376232323664363136653635373537363635373235333734373236313639363736383734343136633663366637373635363432323361373437323735363532633232366436313665363537353736363537323465366635333734366637303730363936653637343136633663366637373635363432323361363636313663373336353263323236373666353736393734363834383631366337343232336136363631366300" + }, + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray" + } + } + } + ] +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 4e563673a..51f71250f 100644 --- a/pom.xml +++ b/pom.xml @@ -25,11 +25,6 @@ jpo-ode-svcs - - - - UTF-8 UTF-8 @@ -99,6 +94,16 @@ 1.18.30 annotationProcessor + + org.springframework.boot + spring-boot-devtools + runtime + + + org.springframework.boot + spring-boot-configuration-processor + annotationProcessor + From 3cb982b8432bbe253faf463f7f5e6236c533589a Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 19 Nov 2024 17:45:02 -0700 Subject: [PATCH 059/264] Added missing imports in TimTransmogrifierTest --- .../jpo/ode/traveler/TimTransmogrifierTest.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 46cb7cc3e..33b089a4f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; import org.json.JSONObject; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -10,14 +11,15 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.model.OdeMsgMetadata; -import us.dot.its.jpo.ode.model.SerialId; +import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; import us.dot.its.jpo.ode.plugin.SNMP; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.SituationDataWarehouse.SDW; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; import us.dot.its.jpo.ode.plugin.j2735.OdeGeoRegion; +import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; +import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; import us.dot.its.jpo.ode.plugin.j2735.timstorage.TravelerInputData; import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.traveler.TimTransmogrifier.TimTransmogrifierException; @@ -27,12 +29,18 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.time.Clock; import java.time.Instant; import java.time.ZoneId; +import java.util.Date; import static org.junit.jupiter.api.Assertions.*; @@ -283,7 +291,7 @@ public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConvers timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); ObjectNode encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - timMetadata.setSchemaVersion(OdeProperties.OUTPUT_SCHEMA_VERSION); + timMetadata.setSchemaVersion(7); // execute String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); From a089aa7439ee2ab8d4bc22c5bc7da53cc87e84ab Mon Sep 17 00:00:00 2001 From: Daniel McCoy Stephenson Date: Wed, 20 Nov 2024 13:02:54 -0700 Subject: [PATCH 060/264] Apply suggestions from code review Co-authored-by: Matt Cook --- .../us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 33b089a4f..af719d9ab 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -262,7 +262,7 @@ void testConvertToXMLMessageFrame() * passed to the TimTransmogrifier.convertToXml() method. */ @Test - public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { + void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { // prepare String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); OdeTravelerInputData odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); @@ -293,11 +293,13 @@ public void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConvers TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); timMetadata.setSchemaVersion(7); + // Set the clock to a fixed instant for value comparison + DateTimeUtils.setClock(Clock.fixed(Instant.parse("2024-11-05T16:51:14.473Z"), ZoneId.of("UTC"))); + // execute String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); // verify - actualXML = actualXML.replaceFirst(".*", "2024-11-05T16:51:14.473Z"); // replace with a fixed value for comparison String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))); Assertions.assertEquals(expectedXml, actualXML); } From 898638d62aa6c7075d3b8b6950fabf5d0dc1ff8e Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 20 Nov 2024 13:55:29 -0700 Subject: [PATCH 061/264] Updated TravelerMessageFromHumanToAsnConverter to ensure compliance with J2735 2024 --- ...ravelerMessageFromHumanToAsnConverter.java | 65 ++++++++++++------- ...lerMessageFromHumanToAsnConverterTest.java | 28 ++++---- 2 files changed, 55 insertions(+), 38 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index 2dc08eccd..d27df53c0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -98,17 +98,21 @@ public class TravelerMessageFromHumanToAsnConverter { private static final String ITEM = "item"; private static final String START_DATE_TIME = "startDateTime"; private static final String DURATON_TIME_MISSPELLED = "duratonTime"; // J2735 2016 Misspelling - private static final String DURATION_TIME = "durationTime"; // used in J2735 2020 + private static final String DURATION_TIME = "durationTime"; // used in J2735 2020/2024 private static final String SSP_TIM_RIGHTS = "sspTimRights"; // used in J2735 2016 private static final String NOT_USED = "notUsed"; // used in J2735 2020 + private static final String DO_NOT_USE_1 = "doNotUse1"; // used in J2735 2024 private static final String SSP_LOCATION_RIGHTS = "sspLocationRights"; // used in J2735 2016 private static final String NOT_USED_1 = "notUsed1"; // used in J2735 2020 + private static final String DO_NOT_USE_2 = "doNotUse2"; // used in J2735 2024 private static final String SSP_MSG_TYPES = "sspMsgTypes"; // used previously private static final String SSP_MSG_RIGHTS_1 = "sspMsgRights1"; // used in J2735 2016 private static final String NOT_USED_2 = "notUsed2"; // used in J2735 2020 + private static final String DO_NOT_USE_3 = "doNotUse3"; // used in J2735 2024 private static final String SSP_MSG_CONTENT = "sspMsgContent"; // used previously private static final String SSP_MSG_RIGHTS_2 = "sspMsgRights2"; // used in J2735 2016 private static final String NOT_USED_3 = "notUsed3"; // used in J2735 2020 + private static final String DO_NOT_USE_4 = "doNotUse4"; // used in J2735 2024 private static final String DATAFRAMES = "dataframes"; private static final String TIME_STAMP = "timeStamp"; public static final String GEOGRAPHICAL_PATH_STRING = "GeographicalPath"; @@ -214,35 +218,13 @@ public static void replaceDataFrame(ObjectNode dataFrame) throws JsonUtilsExcept // // - // replace sspTimRights with notUsed=0 (to conform with J2735 2020) - dataFrame.put(NOT_USED, 0); - dataFrame.remove(SSP_TIM_RIGHTS); - - // replace sspLocationRights with notUsed1=0 (to conform with J2735 2020) - dataFrame.put(NOT_USED_1, 0); - dataFrame.remove(SSP_LOCATION_RIGHTS); - // set frameType value dataFrame.set("frameType", JsonUtils.newNode().put(dataFrame.get("frameType").asText(), EMPTY_FIELD_FLAG)); - // replace sspMsgContent/sspMsgRights1 with notUsed2=0 (to conform with J2735 2020) - dataFrame.put(NOT_USED_2, 0); - dataFrame.remove(SSP_MSG_CONTENT); - dataFrame.remove(SSP_MSG_RIGHTS_1); - - // replace sspMsgTypes/sspMsgRights2 with notUsed3=0 (to conform with J2735 2020) - dataFrame.put(NOT_USED_3, 0); - dataFrame.remove(SSP_MSG_TYPES); - dataFrame.remove(SSP_MSG_RIGHTS_2); + ensureComplianceWithJ2735Revision2024(dataFrame); // priority does not need replacement - // replace duratonTime with durationTime=[value of duratonTime] (to conform with J2735 2020) - if (dataFrame.get(DURATON_TIME_MISSPELLED) != null) { - dataFrame.set(DURATION_TIME, dataFrame.get(DURATON_TIME_MISSPELLED)); - dataFrame.remove(DURATON_TIME_MISSPELLED); - } - // url does not need replacement replaceDataFrameTimestamp(dataFrame); @@ -1116,4 +1098,39 @@ private static String nodeOffsetPointXY(long transformedX, long transformedY) { } } + /** + * Ensures compliance with the J2735 2024 by modifying the given data frame. + * + * @param dataFrame the JSON object representing the data frame to be modified + */ + private static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { + // Remove fields from before J2735 2016 + dataFrame.remove(SSP_MSG_CONTENT); // renamed to sspMsgRights1 + dataFrame.remove(SSP_MSG_TYPES); // renamed to sspMsgRights2 + + // Remove J2735 2016 fields + dataFrame.remove(SSP_TIM_RIGHTS); // renamed to notUsed in J2735 2020 + dataFrame.remove(SSP_LOCATION_RIGHTS); // renamed to notUsed1 in J2735 2020 + dataFrame.remove(SSP_MSG_RIGHTS_1); // renamed to notUsed2 in J2735 2020 + dataFrame.remove(SSP_MSG_RIGHTS_2); // renamed to notUsed3 in J2735 2020 + + // Remove J2735 2020 fields + dataFrame.remove(NOT_USED); // renamed to doNotUse1 in J2735 2024 + dataFrame.remove(NOT_USED_1); // renamed to doNotUse2 in J2735 2024 + dataFrame.remove(NOT_USED_2); // renamed to doNotUse3 in J2735 2024 + dataFrame.remove(NOT_USED_3); // renamed to doNotUse4 in J2735 2024 + + // Add J2735 2024 fields with values of 0 + dataFrame.put(DO_NOT_USE_1, 0); + dataFrame.put(DO_NOT_USE_2, 0); + dataFrame.put(DO_NOT_USE_3, 0); + dataFrame.put(DO_NOT_USE_4, 0); + + // Replace misspelled durationTime field from J2735 2016 with the correct one + if (dataFrame.get(DURATON_TIME_MISSPELLED) != null) { + dataFrame.set(DURATION_TIME, dataFrame.get(DURATON_TIME_MISSPELLED)); + dataFrame.remove(DURATON_TIME_MISSPELLED); + } + } + } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 90d3dd515..eb93ca372 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -61,7 +61,7 @@ public void testAdvisoryNodeLL() throws JsonProcessingException, IOException, Js TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); try { @@ -87,7 +87,7 @@ public void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); try { @@ -113,7 +113,7 @@ public void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); try { @@ -139,7 +139,7 @@ public void testGeometryUnavailable() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -169,7 +169,7 @@ public void testGeometryExitServiceForward() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -199,7 +199,7 @@ public void testGeometryAdvisoryReverse() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -229,7 +229,7 @@ public void testRoadSignIDWorkzone() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); try { @@ -257,7 +257,7 @@ public void testGeometryBothGenericSign() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -287,7 +287,7 @@ public void testPathSpeedLimit() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); try { @@ -376,7 +376,7 @@ public void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsExcepti TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -406,7 +406,7 @@ public void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUt TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -436,7 +436,7 @@ public void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUt TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -466,7 +466,7 @@ public void testOldRegionWithCircle() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -496,7 +496,7 @@ public void testOldRegionWithRegionPointSet() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"notUsed\":0,\"notUsed1\":0,\"notUsed2\":0,\"notUsed3\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); From d27207b87d7fb0e564aa4ed0ff690146a9bbd984 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 20 Nov 2024 14:11:57 -0700 Subject: [PATCH 062/264] Removed error handling from unit tests in `TravelerMessageFromHumanToAsnConverterTest` --- ...lerMessageFromHumanToAsnConverterTest.java | 334 ++++-------------- 1 file changed, 72 insertions(+), 262 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index eb93ca372..2f7198bb5 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -15,15 +15,11 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.builders; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - import java.io.IOException; -import org.json.JSONException; import org.json.JSONObject; import org.json.XML; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -62,21 +58,11 @@ public void testAdvisoryNodeLL() throws JsonProcessingException, IOException, Js ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e1) { - e1.printStackTrace(); - } catch (JsonUtilsException e1) { - e1.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - e.printStackTrace(); - } + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -88,21 +74,11 @@ public void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - e.printStackTrace(); - } catch (JsonUtilsException e) { - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - e.printStackTrace(); - } + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -114,22 +90,11 @@ public void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - e.printStackTrace(); - } catch (JsonUtilsException e) { - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -140,26 +105,12 @@ public void testGeometryUnavailable() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -170,26 +121,12 @@ public void testGeometryExitServiceForward() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -200,26 +137,12 @@ public void testGeometryAdvisoryReverse() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -230,24 +153,11 @@ public void testRoadSignIDWorkzone() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -258,26 +168,12 @@ public void testGeometryBothGenericSign() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -288,37 +184,21 @@ public void testPathSpeedLimit() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test public void testTranslateISOTimeStampToMinuteOfYear() { - assertEquals(232800, - TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); + Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); - assertEquals(232800, - TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); + Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); // Test for invalid timestamp - assertEquals(527040, - TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-15-44T25:66:77.999Z")); + Assertions.assertEquals(527040, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-15-44T25:66:77.999Z")); } @Test @@ -326,22 +206,22 @@ public void testReplaceDataFrameTimestamp() { String fieldName = "startDateTime"; ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - assertNull(startDateTime.get("startDateTime")); - assertEquals(2018, startDateTime.get("startYear").asInt()); - assertEquals(232800, startDateTime.get("startTime").asLong()); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T10:00-06:00"); TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - assertNull(startDateTime.get("startDateTime")); - assertEquals(2018, startDateTime.get("startYear").asInt()); - assertEquals(232800, startDateTime.get("startTime").asLong()); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); // Test for invalid timestamp startDateTime = JsonUtils.newNode().put(fieldName, "2018-15-44T25:66:77.999Z"); TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - assertNull(startDateTime.get("startDateTime")); - assertEquals(0, startDateTime.get("startYear").asInt()); - assertEquals(527040, startDateTime.get("startTime").asLong()); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(0, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(527040, startDateTime.get("startTime").asLong()); } @Test @@ -354,19 +234,19 @@ public void testBuildItem() { // build ITIS code JsonNode actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(itisCode); - assertEquals(expecteditem, actualItem); + Assertions.assertEquals(expecteditem, actualItem); // build number text expectedItisNode.remove(itis); expectedItisNode.put("text", itisCode); actualItem = TravelerMessageFromHumanToAsnConverter.buildItem("'123"); - assertEquals(expecteditem, actualItem); + Assertions.assertEquals(expecteditem, actualItem); // build alphanumeric text String test123 = "test 123"; expectedItisNode.put("text", test123); actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(test123); - assertEquals(expecteditem, actualItem); + Assertions.assertEquals(expecteditem, actualItem); } @Test @@ -377,26 +257,12 @@ public void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsExcepti ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -407,26 +273,12 @@ public void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUt ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -437,26 +289,12 @@ public void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUt ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -467,26 +305,12 @@ public void testOldRegionWithCircle() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } @Test @@ -497,25 +321,11 @@ public void testOldRegionWithRegionPointSet() throws JsonUtilsException { ObjectNode expectedTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - assertEquals(expectedTID.toString(), inputTID.toString()); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); - try { - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - } catch (JSONException e) { - - e.printStackTrace(); - } catch (JsonUtilsException e) { - - e.printStackTrace(); - } - try { - assertNotNull(XML.toString(timObject)); - } catch (JSONException e) { - - e.printStackTrace(); - } - + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); } } From c828175d65ea69b5609cf97bce82133197ad8095 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 20 Nov 2024 14:14:13 -0700 Subject: [PATCH 063/264] Removed access modifiers from `TravelerMessageFromHumanToAsnConverterTest` --- ...lerMessageFromHumanToAsnConverterTest.java | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 2f7198bb5..c1394155a 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -35,22 +35,22 @@ import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; -public class TravelerMessageFromHumanToAsnConverterTest { +class TravelerMessageFromHumanToAsnConverterTest { @Mocked - private Logger logger; + Logger logger; @BeforeEach - public void setup() { + void setup() { new MockUp() { @Mock - public Logger getLogger(String value) { + Logger getLogger(String value) { return logger; } }; } @Test - public void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { + void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); @@ -66,7 +66,7 @@ public void testAdvisoryNodeLL() throws JsonProcessingException, IOException, Js } @Test - public void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { + void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"sspTimRights\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"sspLocationRights\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"sspMsgTypes\":\"1\",\"sspMsgContent\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); @@ -82,7 +82,7 @@ public void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { } @Test - public void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { + void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"sspTimRights\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"sspLocationRights\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"sspMsgTypes\":\"1\",\"sspMsgContent\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); @@ -98,7 +98,7 @@ public void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { } @Test - public void testGeometryUnavailable() throws JsonUtilsException { + void testGeometryUnavailable() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -114,7 +114,7 @@ public void testGeometryUnavailable() throws JsonUtilsException { } @Test - public void testGeometryExitServiceForward() throws JsonUtilsException { + void testGeometryExitServiceForward() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -130,7 +130,7 @@ public void testGeometryExitServiceForward() throws JsonUtilsException { } @Test - public void testGeometryAdvisoryReverse() throws JsonUtilsException { + void testGeometryAdvisoryReverse() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -146,7 +146,7 @@ public void testGeometryAdvisoryReverse() throws JsonUtilsException { } @Test - public void testRoadSignIDWorkzone() throws JsonUtilsException { + void testRoadSignIDWorkzone() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"sspTimRights\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -161,7 +161,7 @@ public void testRoadSignIDWorkzone() throws JsonUtilsException { } @Test - public void testGeometryBothGenericSign() throws JsonUtilsException { + void testGeometryBothGenericSign() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -177,7 +177,7 @@ public void testGeometryBothGenericSign() throws JsonUtilsException { } @Test - public void testPathSpeedLimit() throws JsonUtilsException { + void testPathSpeedLimit() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"sspTimRights\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -192,7 +192,7 @@ public void testPathSpeedLimit() throws JsonUtilsException { } @Test - public void testTranslateISOTimeStampToMinuteOfYear() { + void testTranslateISOTimeStampToMinuteOfYear() { Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); @@ -202,7 +202,7 @@ public void testTranslateISOTimeStampToMinuteOfYear() { } @Test - public void testReplaceDataFrameTimestamp() { + void testReplaceDataFrameTimestamp() { String fieldName = "startDateTime"; ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); @@ -225,7 +225,7 @@ public void testReplaceDataFrameTimestamp() { } @Test - public void testBuildItem() { + void testBuildItem() { String itisCode = "123"; String itis = "itis"; @@ -250,7 +250,7 @@ public void testBuildItem() { } @Test - public void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -266,7 +266,7 @@ public void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsExcepti } @Test - public void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -282,7 +282,7 @@ public void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUt } @Test - public void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -298,7 +298,7 @@ public void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUt } @Test - public void testOldRegionWithCircle() throws JsonUtilsException { + void testOldRegionWithCircle() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -314,7 +314,7 @@ public void testOldRegionWithCircle() throws JsonUtilsException { } @Test - public void testOldRegionWithRegionPointSet() throws JsonUtilsException { + void testOldRegionWithRegionPointSet() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); From 2e1c179dd207a5cc63e2cc1fb1019dadabaccce6 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Thu, 21 Nov 2024 21:34:33 +0000 Subject: [PATCH 064/264] Add TIM POJO and builder --- .../dot/its/jpo/ode/model/OdeTimPayload.java | 6 + .../ode/plugin/j2735/J2735ComputedLane.java | 6 +- .../ode/plugin/j2735/J2735Description.java | 35 ++++ .../ode/plugin/j2735/J2735DirectionOfUse.java | 7 +- .../plugin/j2735/J2735GeographicalPath.java | 71 +++++++ .../j2735/J2735GeometricProjection.java | 45 +++++ .../ode/plugin/j2735/J2735HeadingSlice.java | 20 ++ .../plugin/j2735/J2735LaneDataAttribute.java | 30 +-- .../j2735/J2735LaneDataAttributeList.java | 23 --- .../its/jpo/ode/plugin/j2735/J2735MsgId.java | 26 +++ .../jpo/ode/plugin/j2735/J2735MutcdCode.java | 11 ++ .../plugin/j2735/J2735NodeAttributeSet.java | 63 ++++++ .../plugin/j2735/J2735NodeAttributeSetXY.java | 65 ------ .../plugin/j2735/J2735NodeAttributeXY.java | 20 -- .../j2735/J2735NodeAttributeXYList.java | 23 --- .../its/jpo/ode/plugin/j2735/J2735NodeLL.java | 27 +++ .../jpo/ode/plugin/j2735/J2735NodeListLL.java | 17 ++ .../jpo/ode/plugin/j2735/J2735NodeListXY.java | 17 +- .../plugin/j2735/J2735NodeOffsetPointLL.java | 72 +++++++ .../jpo/ode/plugin/j2735/J2735NodeSetXY.java | 25 --- .../its/jpo/ode/plugin/j2735/J2735NodeXY.java | 39 ++-- .../jpo/ode/plugin/j2735/J2735Node_LL.java | 53 +++++ .../its/jpo/ode/plugin/j2735/J2735Offset.java | 26 +++ .../ode/plugin/j2735/J2735OffsetSystem.java | 26 +++ .../jpo/ode/plugin/j2735/J2735RoadSignId.java | 42 ++++ ...buteXY.java => J2735SegmentAttribute.java} | 2 +- .../j2735/J2735SegmentAttributeXYList.java | 23 --- .../its/jpo/ode/plugin/j2735/J2735Tim.java | 53 +++++ .../plugin/j2735/J2735TravelerDataFrame.java | 126 ++++++++++++ .../plugin/j2735/J2735TravelerInfoType.java | 8 + .../j2735/builders/ComputedLaneBuilder.java | 55 ++++++ .../j2735/builders/GenericLaneBuilder.java | 2 +- .../builders/GeographicalPathBuilder.java | 89 +++++++++ .../builders/LaneDataAttributeBuilder.java | 47 +++++ .../plugin/j2735/builders/NodeBuilder.java | 89 --------- .../plugin/j2735/builders/NodeLLBuilder.java | 185 +++++++++++++++++ .../j2735/builders/NodeListBuilder.java | 40 ---- .../j2735/builders/NodeListLLBuilder.java | 41 ++++ .../j2735/builders/NodeListXYBuilder.java | 60 ++++++ .../plugin/j2735/builders/NodeXYBuilder.java | 187 ++++++++++++++++++ .../j2735/builders/OffsetSystemBuilder.java | 39 ++++ .../j2735/builders/Position3DBuilder.java | 5 +- .../j2735/builders/RoadSignIdBuilder.java | 41 ++++ .../ode/plugin/j2735/builders/TIMBuilder.java | 67 +++++++ .../builders/TravelerDataFrameBuilder.java | 126 ++++++++++++ .../plugin/j2735/J2735DirectionOfUseTest.java | 11 +- .../plugin/j2735/builders/TimBuilderTest.java | 29 +++ .../ode/coder/OdeTimDataCreatorHelper.java | 59 ++++++ .../services/asn1/Asn1DecodedDataRouter.java | 6 +- 49 files changed, 1818 insertions(+), 367 deletions(-) create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttributeList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MsgId.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MutcdCode.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSet.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSetXY.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXY.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXYList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeSetXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735RoadSignId.java rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{J2735SegmentAttributeXY.java => J2735SegmentAttribute.java} (97%) delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXYList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ComputedLaneBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/LaneDataAttributeBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeXYBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/RoadSignIdBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java create mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java index b5e9e0e7b..235c9c0c9 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java @@ -15,6 +15,7 @@ ******************************************************************************/ package us.dot.its.jpo.ode.model; +import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; public class OdeTimPayload extends OdeMsgPayload { @@ -29,4 +30,9 @@ public OdeTimPayload(OdeTravelerInformationMessage tim) { super(tim); this.setData(tim); } + + public OdeTimPayload(J2735Tim tim) { + super(tim); + this.setData(tim); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735ComputedLane.java index 59f073f6f..b4d55ca59 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735ComputedLane.java @@ -5,9 +5,9 @@ public class J2735ComputedLane extends Asn1Object { private static final long serialVersionUID = 1L; - private Integer referenceLaneId; - private Integer offsetXaxis; // could have an object with min and max inside of it - private Integer offsetYaxis; // could have an object with min and max inside of it + private Integer referenceLaneId; + private Integer offsetXaxis; + private Integer offsetYaxis; private Integer rotateXY; private Integer scaleXaxis; private Integer scaleYaxis; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java new file mode 100644 index 000000000..c36022d89 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java @@ -0,0 +1,35 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735Description extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735OffsetSystem path; + private J2735GeometricProjection geometry; + private String oldRegion; //TODO + + public J2735OffsetSystem getPath() { + return path; + } + + public void setPath(J2735OffsetSystem path) { + this.path = path; + } + + public J2735GeometricProjection getGeometry() { + return geometry; + } + + public void setGeometry(J2735GeometricProjection geometry) { + this.geometry = geometry; + } + + public String getOldRegion() { + return oldRegion; + } + + public void setOldRegion(String oldRegion) { + this.oldRegion = oldRegion; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java index c343ca295..3a44d0349 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java @@ -16,7 +16,8 @@ package us.dot.its.jpo.ode.plugin.j2735; public enum J2735DirectionOfUse { - FORWARD, - REVERSE, - BOTH + unavailable, + forward, + reverse, + both } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java new file mode 100644 index 000000000..6f7ddcf64 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java @@ -0,0 +1,71 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735GeographicalPath extends Asn1Object { + private static final long serialVersionUID = 1L; + + private String name; + private J2735RoadSegmentReferenceID id; + private OdePosition3D anchor; + private int laneWidth; + private J2735DirectionOfUse directionality; + private boolean closedPath; + private J2735Description description; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public J2735RoadSegmentReferenceID getId() { + return id; + } + + public void setId(J2735RoadSegmentReferenceID id) { + this.id = id; + } + + public OdePosition3D getAnchor() { + return anchor; + } + + public void setAnchor(OdePosition3D anchor) { + this.anchor = anchor; + } + + public int getLaneWidth() { + return laneWidth; + } + + public void setLaneWidth(int laneWidth) { + this.laneWidth = laneWidth; + } + + public J2735DirectionOfUse getDirectionality() { + return directionality; + } + + public void setDirectionality(J2735DirectionOfUse directionality) { + this.directionality = directionality; + } + + public boolean getClosedPath() { + return closedPath; + } + + public void setClosedPath(boolean closedPath) { + this.closedPath = closedPath; + } + + public J2735Description getDescription() { + return description; + } + + public void setDescription(J2735Description description) { + this.description = description; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java new file mode 100644 index 000000000..81a8bfe38 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java @@ -0,0 +1,45 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Circle; + +public class J2735GeometricProjection extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735HeadingSlice direction; + private J2735Extent extent; + private String laneWidth; + private Circle circle; + + public J2735HeadingSlice getDirection() { + return direction; + } + + public void setDirection(J2735HeadingSlice direction) { + this.direction = direction; + } + + public J2735Extent getExtent() { + return extent; + } + + public void setExtent(J2735Extent extent) { + this.extent = extent; + } + + public String getLaneWidth() { + return laneWidth; + } + + public void setLaneWidth(String laneWidth) { + this.laneWidth = laneWidth; + } + + public Circle getCircle() { + return circle; + } + + public void setCircle(Circle circle) { + this.circle = circle; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java new file mode 100644 index 000000000..ad11b8a7b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java @@ -0,0 +1,20 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +public enum J2735HeadingSlice { + from000_0to022_5degrees, + from022_5to045_0degrees, + from045_0to067_5degrees, + from067_5to090_0degrees, + from090_0to112_5degrees, + from112_5to135_0degrees, + from135_0to157_5degrees, + from157_5to180_0degrees, + from180_0to202_5degrees, + from202_5to225_0degrees, + from225_0to247_5degrees, + from247_5to270_0degrees, + from270_0to292_5degrees, + from292_5to315_0degrees, + from315_0to337_5degrees, + from337_5to360_0degrees +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttribute.java index 5a33a4440..f1614f7cc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttribute.java @@ -7,50 +7,50 @@ public class J2735LaneDataAttribute extends Asn1Object { * */ private static final long serialVersionUID = 1L; - private Integer pathEndPointAngle; - private Integer laneCrownPointCenter; - private Integer laneCrownPointLeft; - private Integer laneCrownPointRight; - private Integer laneAngle; + private int pathEndPointAngle; + private int laneCrownPointCenter; + private int laneCrownPointLeft; + private int laneCrownPointRight; + private int laneAngle; private J2735SpeedLimitList speedLimits; - public Integer getPathEndPointAngle() { + public int getPathEndPointAngle() { return pathEndPointAngle; } - public void setPathEndPointAngle(Integer pathEndPointAngle) { + public void setPathEndPointAngle(int pathEndPointAngle) { this.pathEndPointAngle = pathEndPointAngle; } - public Integer getLaneCrownPointCenter() { + public int getLaneCrownPointCenter() { return laneCrownPointCenter; } - public void setLaneCrownPointCenter(Integer laneCrownPointCenter) { + public void setLaneCrownPointCenter(int laneCrownPointCenter) { this.laneCrownPointCenter = laneCrownPointCenter; } - public Integer getLaneCrownPointLeft() { + public int getLaneCrownPointLeft() { return laneCrownPointLeft; } - public void setLaneCrownPointLeft(Integer laneCrownPointLeft) { + public void setLaneCrownPointLeft(int laneCrownPointLeft) { this.laneCrownPointLeft = laneCrownPointLeft; } - public Integer getLaneCrownPointRight() { + public int getLaneCrownPointRight() { return laneCrownPointRight; } - public void setLaneCrownPointRight(Integer laneCrownPointRight) { + public void setLaneCrownPointRight(int laneCrownPointRight) { this.laneCrownPointRight = laneCrownPointRight; } - public Integer getLaneAngle() { + public int getLaneAngle() { return laneAngle; } - public void setLaneAngle(Integer laneAngle) { + public void setLaneAngle(int laneAngle) { this.laneAngle = laneAngle; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttributeList.java deleted file mode 100644 index 130ad4809..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735LaneDataAttributeList.java +++ /dev/null @@ -1,23 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import java.util.ArrayList; -import java.util.List; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735LaneDataAttributeList extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private List localNode = new ArrayList<>(); - - public List getLocalNode() { - return localNode; - } - - public void setLocalNode(List localNode) { - this.localNode = localNode; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MsgId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MsgId.java new file mode 100644 index 000000000..1b729cee5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MsgId.java @@ -0,0 +1,26 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735MsgId extends Asn1Object { + private static final long serialVersionUID = 1L; + + private String furtherInfoID; + private J2735RoadSignId roadSignID; + + public String getFurtherInfoId() { + return furtherInfoID; + } + + public void setFurtherInfoId(String furtherInfoID) { + this.furtherInfoID = furtherInfoID; + } + + public J2735RoadSignId getRoadSignID() { + return roadSignID; + } + + public void setRoadSignID(J2735RoadSignId roadSignID) { + this.roadSignID = roadSignID; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MutcdCode.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MutcdCode.java new file mode 100644 index 000000000..744f1aa36 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735MutcdCode.java @@ -0,0 +1,11 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +public enum J2735MutcdCode { + none, + regulatory, + warning, + maintenance, + motoristService, + guide, + rec, +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSet.java new file mode 100644 index 000000000..3b0493ef8 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSet.java @@ -0,0 +1,63 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735NodeAttributeSet extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735NodeAttribute[] localNode; + private J2735SegmentAttribute[] disabled; + private J2735SegmentAttribute[] enabled; + private J2735LaneDataAttribute[] data; + private Integer dWidth; + private Integer dElevation; + + public J2735NodeAttribute[] getLocalNode() { + return localNode; + } + + public void setLocalNode(J2735NodeAttribute[] localNode) { + this.localNode = localNode; + } + + public J2735SegmentAttribute[] getDisabled() { + return disabled; + } + + public void setDisabled(J2735SegmentAttribute[] disabled) { + this.disabled = disabled; + } + + public J2735SegmentAttribute[] getEnabled() { + return enabled; + } + + public void setEnabled(J2735SegmentAttribute[] enabled) { + this.enabled = enabled; + } + + public J2735LaneDataAttribute[] getData() { + return data; + } + + public void setData(J2735LaneDataAttribute[] data) { + this.data = data; + } + + public Integer getdWidth() { + return dWidth; + } + + public void setdWidth(Integer dWidth) { + this.dWidth = dWidth; + } + + public Integer getdElevation() { + return dElevation; + } + + public void setdElevation(Integer dElevation) { + this.dElevation = dElevation; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSetXY.java deleted file mode 100644 index 7c8ef06dd..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeSetXY.java +++ /dev/null @@ -1,65 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeAttributeSetXY extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private J2735NodeAttributeXYList localNode; - private J2735SegmentAttributeXYList disabled; - private J2735SegmentAttributeXYList enabled; - private J2735LaneDataAttributeList data; - private Integer dWidth; - private Integer dElevation; - - public J2735NodeAttributeXYList getLocalNode() { - return localNode; - } - - public void setLocalNode(J2735NodeAttributeXYList localNode) { - this.localNode = localNode; - } - - public J2735SegmentAttributeXYList getDisabled() { - return disabled; - } - - public void setDisabled(J2735SegmentAttributeXYList disabled) { - this.disabled = disabled; - } - - public J2735SegmentAttributeXYList getEnabled() { - return enabled; - } - - public void setEnabled(J2735SegmentAttributeXYList enabled) { - this.enabled = enabled; - } - - public J2735LaneDataAttributeList getData() { - return data; - } - - public void setData(J2735LaneDataAttributeList data) { - this.data = data; - } - - public Integer getdWidth() { - return dWidth; - } - - public void setdWidth(Integer dWidth) { - this.dWidth = dWidth; - } - - public Integer getdElevation() { - return dElevation; - } - - public void setdElevation(Integer dElevation) { - this.dElevation = dElevation; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXY.java deleted file mode 100644 index f584e05a9..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXY.java +++ /dev/null @@ -1,20 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeAttributeXY extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private J2735NodeAttribute nodeAttrList; - - public J2735NodeAttribute getNodeAttrList() { - return nodeAttrList; - } - - public void setNodeAttrList(J2735NodeAttribute nodeAttrList) { - this.nodeAttrList = nodeAttrList; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXYList.java deleted file mode 100644 index ab5e46e8f..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeAttributeXYList.java +++ /dev/null @@ -1,23 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import java.util.ArrayList; -import java.util.List; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeAttributeXYList extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private List localNode = new ArrayList<>(); - - public List getLocalNode() { - return localNode; - } - - public void setLocalNode(List localNode) { - this.localNode = localNode; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java new file mode 100644 index 000000000..4ac84417a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735NodeLL extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735NodeOffsetPointLL delta; + private J2735NodeAttributeSet attributes; + + public J2735NodeOffsetPointLL getDelta() { + return delta; + } + + public void setDelta(J2735NodeOffsetPointLL delta) { + this.delta = delta; + } + + public J2735NodeAttributeSet getAttributes() { + return attributes; + } + + public void setAttributes(J2735NodeAttributeSet attributes) { + this.attributes = attributes; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java new file mode 100644 index 000000000..009650712 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java @@ -0,0 +1,17 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735NodeListLL extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735NodeLL[] nodes; + + public J2735NodeLL[] getNodes() { + return nodes; + } + + public void setNodes(J2735NodeLL[] nodes) { + this.nodes = nodes; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java index 9be72df3d..d0e2555c1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java @@ -1,7 +1,5 @@ package us.dot.its.jpo.ode.plugin.j2735; -import com.fasterxml.jackson.annotation.JsonProperty; - import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; public class J2735NodeListXY extends Asn1Object { @@ -9,23 +7,22 @@ public class J2735NodeListXY extends Asn1Object { * */ private static final long serialVersionUID = 1L; - private J2735NodeSetXY nodes; - private J2735ComputedLane computed; + private J2735NodeXY[] nodes; + private J2735ComputedLane[] computed; - @JsonProperty("nodes") - public J2735NodeSetXY getNodes() { + public J2735NodeXY[] getNodes() { return nodes; } - public void setNodes(J2735NodeSetXY nodeList) { - this.nodes = nodeList; + public void setNodes(J2735NodeXY[] nodes) { + this.nodes = nodes; } - public J2735ComputedLane getComputed() { + public J2735ComputedLane[] getComputed() { return computed; } - public void setComputed(J2735ComputedLane computed) { + public void setComputed(J2735ComputedLane[] computed) { this.computed = computed; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java new file mode 100644 index 000000000..2465bbadb --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java @@ -0,0 +1,72 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735NodeOffsetPointLL extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735Node_LL nodeLL1; + private J2735Node_LL nodeLL2; + private J2735Node_LL nodeLL3; + private J2735Node_LL nodeLL4; + private J2735Node_LL nodeLL5; + private J2735Node_LL nodeLL6; + private J2735NodeLLmD64b nodeLatLon; + + public J2735Node_LL getNodeLL1() { + return nodeLL1; + } + + public void setNodeLL1(J2735Node_LL nodeLL1) { + this.nodeLL1 = nodeLL1; + } + + public J2735Node_LL getNodeLL2() { + return nodeLL2; + } + + public void setNodeLL2(J2735Node_LL nodeLL2) { + this.nodeLL2 = nodeLL2; + } + + public J2735Node_LL getNodeLL3() { + return nodeLL3; + } + + public void setNodeLL3(J2735Node_LL nodeLL3) { + this.nodeLL3 = nodeLL3; + } + + public J2735Node_LL getNodeLL4() { + return nodeLL4; + } + + public void setNodeLL4(J2735Node_LL nodeLL4) { + this.nodeLL4 = nodeLL4; + } + + public J2735Node_LL getNodeLL5() { + return nodeLL5; + } + + public void setNodeLL5(J2735Node_LL nodeLL5) { + this.nodeLL5 = nodeLL5; + } + + public J2735Node_LL getNodeLL6() { + return nodeLL6; + } + + public void setNodeLL6(J2735Node_LL nodeLL6) { + this.nodeLL6 = nodeLL6; + } + + public J2735NodeLLmD64b getNodeLatLon() { + return nodeLatLon; + } + + public void setNodeLatLon(J2735NodeLLmD64b nodeLatLon) { + this.nodeLatLon = nodeLatLon; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeSetXY.java deleted file mode 100644 index 536814d54..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeSetXY.java +++ /dev/null @@ -1,25 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import java.util.ArrayList; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeSetXY extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private List NodeXY = new ArrayList<>(); - - @JsonProperty("NodeXY") - public List getNodes() { - return NodeXY; - } - public void setNodes(List NodeXY) { - this.NodeXY = NodeXY; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeXY.java index 1de3ef308..4f03460ec 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeXY.java @@ -3,23 +3,24 @@ import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; public class J2735NodeXY extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private J2735NodeOffsetPointXY delta ; - private J2735NodeAttributeSetXY attributes ; - public J2735NodeOffsetPointXY getDelta() { - return delta; - } - public void setDelta(J2735NodeOffsetPointXY delta) { - this.delta = delta; - } - public J2735NodeAttributeSetXY getAttributes() { - return attributes; - } - public void setAttributes(J2735NodeAttributeSetXY attributes) { - this.attributes = attributes; - } - + private static final long serialVersionUID = 1L; + + private J2735NodeOffsetPointXY delta; + private J2735NodeAttributeSet attributes; + + public J2735NodeOffsetPointXY getDelta() { + return delta; + } + + public void setDelta(J2735NodeOffsetPointXY delta) { + this.delta = delta; + } + + public J2735NodeAttributeSet getAttributes() { + return attributes; + } + + public void setAttributes(J2735NodeAttributeSet attributes) { + this.attributes = attributes; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java new file mode 100644 index 000000000..fa3e18c36 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright 2018 572682 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ******************************************************************************/ +package us.dot.its.jpo.ode.plugin.j2735; + +import java.math.BigDecimal; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735Node_LL extends Asn1Object { + private static final long serialVersionUID = 1L; + + private BigDecimal lon; + private BigDecimal lat; + + public J2735Node_LL() { + super(); + } + + public J2735Node_LL(BigDecimal lon, BigDecimal lat) { + super(); + this.lon = lon; + this.lat = lat; + } + + public BigDecimal getLon() { + return lon; + } + + public void setLon(BigDecimal lon) { + this.lon = lon; + } + + public BigDecimal getLat() { + return lat; + } + + public void setLat(BigDecimal lat) { + this.lat = lat; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java new file mode 100644 index 000000000..788cdc71b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java @@ -0,0 +1,26 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735Offset extends Asn1Object { + private static final long serialVersionUID = 1L; + + private J2735NodeListXY xy; + private J2735NodeListLL ll; + + public J2735NodeListXY getXY() { + return xy; + } + + public void setXY(J2735NodeListXY xy) { + this.xy = xy; + } + + public J2735NodeListLL getLL() { + return ll; + } + + public void setLL(J2735NodeListLL ll) { + this.ll = ll; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java new file mode 100644 index 000000000..186af2e1f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java @@ -0,0 +1,26 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735OffsetSystem extends Asn1Object { + private static final long serialVersionUID = 1L; + + private int scale; + private J2735Offset offset; + + public int getScale() { + return scale; + } + + public void setScale(int scale) { + this.scale = scale; + } + + public J2735Offset getOffset() { + return offset; + } + + public void setOffset(J2735Offset offset) { + this.offset = offset; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735RoadSignId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735RoadSignId.java new file mode 100644 index 000000000..c45059b70 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735RoadSignId.java @@ -0,0 +1,42 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735RoadSignId extends Asn1Object { + private OdePosition3D position; + private String viewAngle; + private J2735MutcdCode mutcdCode; + private String crc; + + public OdePosition3D getPosition() { + return position; + } + + public void setPosition(OdePosition3D position) { + this.position = position; + } + + public String getViewAngle() { + return viewAngle; + } + + public void setViewAngle(String viewAngle) { + this.viewAngle = viewAngle; + } + + public J2735MutcdCode getMutcdCode() { + return mutcdCode; + } + + public void setMutcdCode(J2735MutcdCode mutcdCode) { + this.mutcdCode = mutcdCode; + } + + public String getCrc() { + return crc; + } + + public void setCrc(String crc) { + this.crc = crc; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttribute.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttribute.java index dd8b41e92..6c6319f1f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttribute.java @@ -1,6 +1,6 @@ package us.dot.its.jpo.ode.plugin.j2735; -public enum J2735SegmentAttributeXY { +public enum J2735SegmentAttribute { reserved , doNotBlock , whiteLine , diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXYList.java deleted file mode 100644 index eb4cbd207..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735SegmentAttributeXYList.java +++ /dev/null @@ -1,23 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import java.util.ArrayList; -import java.util.List; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735SegmentAttributeXYList extends Asn1Object { - /** - * - */ - private static final long serialVersionUID = 1L; - private List segAttrList = new ArrayList<>(); - - public List getSegAttrList() { - return segAttrList; - } - - public void setSegAttrList(List segAttrList) { - this.segAttrList = segAttrList; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java new file mode 100644 index 000000000..3be7eb30d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; + +public class J2735Tim extends Asn1Object { + private static final long serialVersionUID = 1L; + + private String msgCnt; + private String timeStamp; + private String packetID; + private String urlB; + private J2735TravelerDataFrame[] dataFrames; + + public String getMsgCnt() { + return msgCnt; + } + + public void setMsgCnt(String msgCnt) { + this.msgCnt = msgCnt; + } + + public String getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getPacketID() { + return packetID; + } + + public void setPacketID(String packetID) { + this.packetID = packetID; + } + + public String getUrlB() { + return urlB; + } + + public void setUrlB(String urlB) { + this.urlB = urlB; + } + + public J2735TravelerDataFrame[] getDataFrames() { + return dataFrames; + } + + public void setDataFrames(J2735TravelerDataFrame[] dataFrames) { + this.dataFrames = dataFrames; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java new file mode 100644 index 000000000..1093f1cc9 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java @@ -0,0 +1,126 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Content; + +public class J2735TravelerDataFrame extends Asn1Object { + private static final long serialVersionUID = 1L; + + private String notUsed; + private J2735TravelerInfoType frameType; + private J2735MsgId msgId; + private String startYear; + private String startTime; + private String durationTime; + private String priority; + private String notUsed1; + private J2735GeographicalPath[] regions; + private String notUsed2; + private String notUsed3; + private Content content; + private String url; + + public String getNotUsed() { + return notUsed; + } + + public void setNotUsed(String notUsed) { + this.notUsed = notUsed; + } + + public J2735TravelerInfoType getFrameType() { + return frameType; + } + + public void setFrameType(J2735TravelerInfoType frameType) { + this.frameType = frameType; + } + + public J2735MsgId getMsgId() { + return msgId; + } + + public void setMsgId(J2735MsgId msgId) { + this.msgId = msgId; + } + + public String getStartYear() { + return startYear; + } + + public void setStartYear(String startYear) { + this.startYear = startYear; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getDurationTime() { + return durationTime; + } + + public void setDurationTime(String durationTime) { + this.durationTime = durationTime; + } + + public String getPriority() { + return priority; + } + + public void setPriority(String priority) { + this.priority = priority; + } + + public String getNotUsed1() { + return notUsed1; + } + + public void setNotUsed1(String notUsed1) { + this.notUsed1 = notUsed1; + } + + public J2735GeographicalPath[] getRegions() { + return regions; + } + + public void setRegions(J2735GeographicalPath[] regions) { + this.regions = regions; + } + + public String getNotUsed2() { + return notUsed2; + } + + public void setNotUsed2(String notUsed2) { + this.notUsed2 = notUsed2; + } + + public String getNotUsed3() { + return notUsed3; + } + + public void setNotUsed3(String notUsed3) { + this.notUsed3 = notUsed3; + } + + public Content getContent() { + return content; + } + + public void setContent(Content content) { + this.content = content; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java new file mode 100644 index 000000000..016f9b1d1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java @@ -0,0 +1,8 @@ +package us.dot.its.jpo.ode.plugin.j2735; + +public enum J2735TravelerInfoType { + unknown, + advisory, + roadSignage, + commercialSignage, +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ComputedLaneBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ComputedLaneBuilder.java new file mode 100644 index 000000000..d143367f3 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ComputedLaneBuilder.java @@ -0,0 +1,55 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735ComputedLane; + +public class ComputedLaneBuilder { + private ComputedLaneBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735ComputedLane genericComputedLane(JsonNode computed) { + J2735ComputedLane computedLane = new J2735ComputedLane(); + + JsonNode referenceLaneId = computed.get("referenceLaneId"); + if (referenceLaneId != null) { + computedLane.setReferenceLaneId(referenceLaneId.asInt()); + } + + JsonNode offsetXaxis = computed.get("offsetXaxis"); + if (offsetXaxis != null) { + if (offsetXaxis.get("small") != null) { + computedLane.setOffsetXaxis(offsetXaxis.get("small").asInt()); + } else if (offsetXaxis.get("large") != null) { + computedLane.setOffsetXaxis(offsetXaxis.get("large").asInt()); + } + } + + JsonNode offsetYaxis = computed.get("offsetYaxis"); + if (offsetYaxis != null) { + if (offsetYaxis.get("small") != null) { + computedLane.setOffsetYaxis(offsetYaxis.get("small").asInt()); + } else if (offsetYaxis.get("large") != null) { + computedLane.setOffsetYaxis(offsetYaxis.get("large").asInt()); + } + } + + JsonNode rotateXY = computed.get("rotateXY"); + if (rotateXY != null) { + computedLane.setRotateXY(rotateXY.asInt()); + } + + JsonNode scaleXaxis = computed.get("scaleXaxis"); + if (scaleXaxis != null) { + computedLane.setScaleXaxis(scaleXaxis.asInt()); + } + + JsonNode scaleYaxis = computed.get("scaleYaxis"); + if (scaleYaxis != null) { + computedLane.setScaleYaxis(scaleYaxis.asInt()); + } + + return computedLane; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GenericLaneBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GenericLaneBuilder.java index 30d6eaf59..d7dd7ec10 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GenericLaneBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GenericLaneBuilder.java @@ -106,7 +106,7 @@ public static J2735GenericLane genericGenericLane(JsonNode laneSetNode) { JsonNode nodeList = laneSetNode.get("nodeList"); if (nodeList != null) { - genericLane.setNodeList(NodeListBuilder.genericNodeList(nodeList)); + genericLane.setNodeList(NodeListXYBuilder.genericNodeListXY(nodeList)); } JsonNode connectsTo = laneSetNode.get("connectsTo"); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java new file mode 100644 index 000000000..b5e6045ba --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java @@ -0,0 +1,89 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.DsrcPosition3D; +import us.dot.its.jpo.ode.plugin.j2735.J2735Description; +import us.dot.its.jpo.ode.plugin.j2735.J2735DirectionOfUse; +import us.dot.its.jpo.ode.plugin.j2735.J2735GeographicalPath; +import us.dot.its.jpo.ode.plugin.j2735.J2735RoadSegmentReferenceID; + +public class GeographicalPathBuilder { + private GeographicalPathBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735GeographicalPath genericGeographicalPath(JsonNode geographicalPath) { + J2735GeographicalPath genericGeographicalPath = new J2735GeographicalPath(); + + JsonNode name = geographicalPath.get("name"); + if (name != null) { + genericGeographicalPath.setName(name.asText()); + } + + JsonNode id = geographicalPath.get("id"); + if (id != null) { + J2735RoadSegmentReferenceID idObj = new J2735RoadSegmentReferenceID(); + + JsonNode idRegion = id.get("region"); + if (idRegion != null) { + idObj.setRegion(idRegion.asInt()); + } + + JsonNode idId = id.get("id"); + if (idId != null) { + idObj.setId(idId.asInt()); + } + + genericGeographicalPath.setId(idObj); + } + + JsonNode anchor = geographicalPath.get("anchor"); + if (anchor != null) { + DsrcPosition3D dsrcPosition3d = Position3DBuilder.dsrcPosition3D(anchor); + genericGeographicalPath.setAnchor(Position3DBuilder.odePosition3D(dsrcPosition3d)); + } + + JsonNode laneWidth = geographicalPath.get("laneWidth"); + if (laneWidth != null) { + genericGeographicalPath.setLaneWidth(laneWidth.asInt()); + } + + JsonNode directionality = geographicalPath.get("directionality"); + if (directionality != null) { + String directionalityValue = directionality.fields().next().getKey(); + genericGeographicalPath.setDirectionality(J2735DirectionOfUse.valueOf(directionalityValue)); + } + + JsonNode closedPath = geographicalPath.get("closedPath"); + if (closedPath != null) { + boolean closedPathValue = "true".equals(closedPath.fields().next().getKey()); + genericGeographicalPath.setClosedPath(closedPathValue); + } + + JsonNode description = geographicalPath.get("description"); + if (description != null) { + J2735Description descriptionObj = new J2735Description(); + + JsonNode path = description.get("path"); + if (path != null) { + descriptionObj.setPath(OffsetSystemBuilder.genericOffsetSystem(path)); + } + + JsonNode geometry = description.get("geometry"); + if (geometry != null) { + // RoadSignIdBuilder.genericRoadSignId(roadSignID) + descriptionObj.setGeometry(null); + } + + JsonNode oldRegion = description.get("oldRegion"); + if (oldRegion != null) { + descriptionObj.setOldRegion(null); + } + + genericGeographicalPath.setDescription(descriptionObj); + } + + return genericGeographicalPath; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/LaneDataAttributeBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/LaneDataAttributeBuilder.java new file mode 100644 index 000000000..072f66bf8 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/LaneDataAttributeBuilder.java @@ -0,0 +1,47 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735LaneDataAttribute; + +public class LaneDataAttributeBuilder { + private LaneDataAttributeBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735LaneDataAttribute genericLaneDataAttribute(JsonNode data) { + J2735LaneDataAttribute laneDataAttribute = new J2735LaneDataAttribute(); + + JsonNode pathEndPointAngle = data.get("pathEndPointAngle"); + if (pathEndPointAngle != null) { + laneDataAttribute.setPathEndPointAngle(pathEndPointAngle.asInt()); + } + + JsonNode laneCrownPointCenter = data.get("laneCrownPointCenter"); + if (laneCrownPointCenter != null) { + laneDataAttribute.setLaneCrownPointCenter(laneCrownPointCenter.asInt()); + } + + JsonNode laneCrownPointLeft = data.get("laneCrownPointLeft"); + if (laneCrownPointLeft != null) { + laneDataAttribute.setLaneCrownPointLeft(laneCrownPointLeft.asInt()); + } + + JsonNode laneCrownPointRight = data.get("laneCrownPointRight"); + if (laneCrownPointRight != null) { + laneDataAttribute.setLaneCrownPointRight(laneCrownPointRight.asInt()); + } + + JsonNode laneAngle = data.get("laneAngle"); + if (laneAngle != null) { + laneDataAttribute.setLaneAngle(laneAngle.asInt()); + } + + JsonNode speedLimits = data.get("speedLimits"); + if (speedLimits != null) { + laneDataAttribute.setSpeedLimits(SpeedLimitListBuilder.genericSpeedLimitList(speedLimits)); + } + + return laneDataAttribute; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeBuilder.java deleted file mode 100644 index 2516205a4..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeBuilder.java +++ /dev/null @@ -1,89 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.math.BigDecimal; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLLmD64b; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeOffsetPointXY; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeXY; -import us.dot.its.jpo.ode.plugin.j2735.J2735Node_XY; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttributeSetXY; - - -public class NodeBuilder { - - public static J2735NodeXY genericNode(JsonNode NodeJson) { - J2735NodeXY nodeXY = new J2735NodeXY(); - if (NodeJson.get("delta") != null) { - J2735NodeOffsetPointXY pointoffsetXY = new J2735NodeOffsetPointXY(); - JsonNode NodeOffsetNode = NodeJson.get("delta"); - if(NodeOffsetNode.get("node-XY1") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY1").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY1").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY1(point); - } - if(NodeOffsetNode.get("node-XY2") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY2").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY2").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY2(point); - } - if(NodeOffsetNode.get("node-XY3") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY3").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY3").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY3(point); - } - if(NodeOffsetNode.get("node-XY4") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY4").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY4").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY4(point); - } - if(NodeOffsetNode.get("node-XY5") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY5").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY5").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY5(point); - } - if(NodeOffsetNode.get("node-XY6") != null) - { - BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY6").get("x").asInt()); - BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY6").get("y").asInt()); - J2735Node_XY point = new J2735Node_XY(x,y); - pointoffsetXY.setNodeXY6(point); - } - if(NodeOffsetNode.get("node-LatLon") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lat").asInt()); - J2735NodeLLmD64b point = new J2735NodeLLmD64b(lon,lat); - pointoffsetXY.setNodeLatLon(point); - } - nodeXY.setDelta(pointoffsetXY); - } - - if (NodeJson.get("attributes") != null) { - J2735NodeAttributeSetXY attributeSetXY = new J2735NodeAttributeSetXY(); - JsonNode attributes = NodeJson.get("attributes"); - - // TODO: finish attributes with all of the lists - - if(attributes.get("dElevation") != null) - { - attributeSetXY.setdElevation(attributes.get("dElevation").asInt()); - } - - nodeXY.setAttributes(attributeSetXY); - } - return nodeXY; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java new file mode 100644 index 000000000..3d96b68c2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java @@ -0,0 +1,185 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttribute; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttributeSet; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLL; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLLmD64b; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeOffsetPointLL; +import us.dot.its.jpo.ode.plugin.j2735.J2735Node_LL; +import us.dot.its.jpo.ode.plugin.j2735.J2735SegmentAttribute; + +public class NodeLLBuilder { + private NodeLLBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735NodeLL genericNodeLL(JsonNode NodeJson) { + J2735NodeLL nodeLL = new J2735NodeLL(); + if (NodeJson.get("delta") != null) { + J2735NodeOffsetPointLL pointoffsetLL = new J2735NodeOffsetPointLL(); + JsonNode NodeOffsetNode = NodeJson.get("delta"); + if(NodeOffsetNode.get("node-LL1") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL1").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL1").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL1(point); + } + if(NodeOffsetNode.get("node-LL2") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL2").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL2").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL2(point); + } + if(NodeOffsetNode.get("node-LL3") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL3").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL3").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL3(point); + } + if(NodeOffsetNode.get("node-LL4") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL4").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL4").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL4(point); + } + if(NodeOffsetNode.get("node-LL5") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL5").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL5").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL5(point); + } + if(NodeOffsetNode.get("node-LL6") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL6").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL6").get("lat").asInt()); + J2735Node_LL point = new J2735Node_LL(lon,lat); + pointoffsetLL.setNodeLL6(point); + } + if(NodeOffsetNode.get("node-LatLon") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lat").asInt()); + J2735NodeLLmD64b point = new J2735NodeLLmD64b(lon,lat); + pointoffsetLL.setNodeLatLon(point); + } + nodeLL.setDelta(pointoffsetLL); + } + + if (NodeJson.get("attributes") != null) { + J2735NodeAttributeSet attributeSet = new J2735NodeAttributeSet(); + JsonNode attributes = NodeJson.get("attributes"); + + JsonNode localNode = attributes.get("localNode"); + if (localNode != null) { + JsonNode nodeAttributeLL = localNode.get("NodeAttributeLL"); + if (nodeAttributeLL != null) { + List naList = new ArrayList<>(); + + if (nodeAttributeLL.isArray()) { + Iterator elements = nodeAttributeLL.elements(); + + while (elements.hasNext()) { + String nodeAttributeValue = elements.next().fields().next().getKey(); + naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); + } + } else { + String nodeAttributeValue = nodeAttributeLL.fields().next().getKey(); + naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); + } + + attributeSet.setLocalNode(naList.toArray(new J2735NodeAttribute[0])); + } + } + + JsonNode disabled = attributes.get("disabled"); + if (disabled != null) { + JsonNode segmentAttributeLL = disabled.get("SegmentAttributeLL"); + if (segmentAttributeLL != null) { + List saList = new ArrayList<>(); + + if (segmentAttributeLL.isArray()) { + Iterator elements = segmentAttributeLL.elements(); + + while (elements.hasNext()) { + String segmentAttributeValue = elements.next().fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + } else { + String segmentAttributeValue = segmentAttributeLL.fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + + attributeSet.setDisabled(saList.toArray(new J2735SegmentAttribute[0])); + } + } + + JsonNode enabled = attributes.get("enabled"); + if (enabled != null) { + JsonNode segmentAttributeLL = enabled.get("SegmentAttributeLL"); + if (segmentAttributeLL != null) { + List saList = new ArrayList<>(); + + if (segmentAttributeLL.isArray()) { + Iterator elements = segmentAttributeLL.elements(); + + while (elements.hasNext()) { + String segmentAttributeValue = elements.next().fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + } else { + String segmentAttributeValue = segmentAttributeLL.fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + + attributeSet.setEnabled(saList.toArray(new J2735SegmentAttribute[0])); + } + } + + JsonNode data = attributes.get("data"); + if (data != null) { + JsonNode laneDataAttribute = data.get("LaneDataAttribute"); + if (laneDataAttribute != null) { + List ldaList = new ArrayList<>(); + + if (laneDataAttribute.isArray()) { + Iterator elements = laneDataAttribute.elements(); + + while (elements.hasNext()) { + ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(elements.next())); + } + } else { + ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(laneDataAttribute)); + } + + attributeSet.setData(ldaList.toArray(new J2735LaneDataAttribute[0])); + } + } + + if(attributes.get("dWidth") != null) + { + attributeSet.setdWidth(attributes.get("dWidth").asInt()); + } + + if(attributes.get("dElevation") != null) + { + attributeSet.setdElevation(attributes.get("dElevation").asInt()); + } + + nodeLL.setAttributes(attributeSet); + } + return nodeLL; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListBuilder.java deleted file mode 100644 index 264aa6f89..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListBuilder.java +++ /dev/null @@ -1,40 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.util.Iterator; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeListXY; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeSetXY; - -public class NodeListBuilder { - private NodeListBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735NodeListXY genericNodeList(JsonNode nodeListNode) { - J2735NodeListXY nodeList = new J2735NodeListXY(); - - if (nodeListNode.get("nodes") != null) { - J2735NodeSetXY nodeSet = new J2735NodeSetXY(); - - JsonNode nodeXY = nodeListNode.get("nodes").get("NodeXY"); - if (nodeXY != null && nodeXY.isArray()) { - Iterator elements = nodeXY.elements(); - - while (elements.hasNext()) { - nodeSet.getNodes().add(NodeBuilder.genericNode(elements.next())); - } - } else if (nodeXY != null) { - nodeSet.getNodes().add(NodeBuilder.genericNode(nodeXY)); - } - - nodeList.setNodes(nodeSet); - } else if (nodeListNode.get("computed") != null) { - // TODO - } - - return nodeList; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java new file mode 100644 index 000000000..949266536 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLL; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeListLL; + +public class NodeListLLBuilder { + private NodeListLLBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735NodeListLL genericNodeListLL(JsonNode nodeListNode) { + J2735NodeListLL nodeList = new J2735NodeListLL(); + + if (nodeListNode.get("nodes") != null) { + JsonNode nodeLL = nodeListNode.get("nodes").get("NodeLL"); + if (nodeLL != null) { + List nllList = new ArrayList<>(); + + if (nodeLL.isArray()) { + Iterator elements = nodeLL.elements(); + + while (elements.hasNext()) { + nllList.add(NodeLLBuilder.genericNodeLL(elements.next())); + } + } else { + nllList.add(NodeLLBuilder.genericNodeLL(nodeLL)); + } + + nodeList.setNodes(nllList.toArray(new J2735NodeLL[0])); + } + } + + return nodeList; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java new file mode 100644 index 000000000..fa981e56c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java @@ -0,0 +1,60 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735ComputedLane; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeListXY; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeXY; + +public class NodeListXYBuilder { + private NodeListXYBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735NodeListXY genericNodeListXY(JsonNode nodeListNode) { + J2735NodeListXY nodeList = new J2735NodeListXY(); + + if (nodeListNode.get("nodes") != null) { + JsonNode nodeXY = nodeListNode.get("nodes").get("NodeXY"); + if (nodeXY != null) { + List nxyList = new ArrayList<>(); + + if (nodeXY.isArray()) { + Iterator elements = nodeXY.elements(); + + while (elements.hasNext()) { + nxyList.add(NodeXYBuilder.genericNodeXY(elements.next())); + } + } else { + nxyList.add(NodeXYBuilder.genericNodeXY(nodeXY)); + } + + nodeList.setNodes(nxyList.toArray(new J2735NodeXY[0])); + } + } else if (nodeListNode.get("computed") != null) { + JsonNode computedLane = nodeListNode.get("computed").get("ComputedLane"); + if (computedLane != null) { + List clList = new ArrayList<>(); + + if (computedLane.isArray()) { + Iterator elements = computedLane.elements(); + + while (elements.hasNext()) { + clList.add(ComputedLaneBuilder.genericComputedLane(elements.next())); + } + } else { + clList.add(ComputedLaneBuilder.genericComputedLane(computedLane)); + } + + nodeList.setComputed(clList.toArray(new J2735ComputedLane[0])); + } + } + + return nodeList; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeXYBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeXYBuilder.java new file mode 100644 index 000000000..a17da3c71 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeXYBuilder.java @@ -0,0 +1,187 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLLmD64b; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeOffsetPointXY; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeXY; +import us.dot.its.jpo.ode.plugin.j2735.J2735Node_XY; +import us.dot.its.jpo.ode.plugin.j2735.J2735SegmentAttribute; +import us.dot.its.jpo.ode.plugin.j2735.J2735LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttribute; +import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttributeSet; + + +public class NodeXYBuilder { + private NodeXYBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735NodeXY genericNodeXY(JsonNode NodeJson) { + J2735NodeXY nodeXY = new J2735NodeXY(); + if (NodeJson.get("delta") != null) { + J2735NodeOffsetPointXY pointoffsetXY = new J2735NodeOffsetPointXY(); + JsonNode NodeOffsetNode = NodeJson.get("delta"); + if(NodeOffsetNode.get("node-XY1") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY1").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY1").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY1(point); + } + if(NodeOffsetNode.get("node-XY2") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY2").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY2").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY2(point); + } + if(NodeOffsetNode.get("node-XY3") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY3").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY3").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY3(point); + } + if(NodeOffsetNode.get("node-XY4") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY4").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY4").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY4(point); + } + if(NodeOffsetNode.get("node-XY5") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY5").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY5").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY5(point); + } + if(NodeOffsetNode.get("node-XY6") != null) + { + BigDecimal x =BigDecimal.valueOf( NodeOffsetNode.get("node-XY6").get("x").asInt()); + BigDecimal y =BigDecimal.valueOf( NodeOffsetNode.get("node-XY6").get("y").asInt()); + J2735Node_XY point = new J2735Node_XY(x,y); + pointoffsetXY.setNodeXY6(point); + } + if(NodeOffsetNode.get("node-LatLon") != null) + { + BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lon").asInt()); + BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lat").asInt()); + J2735NodeLLmD64b point = new J2735NodeLLmD64b(lon,lat); + pointoffsetXY.setNodeLatLon(point); + } + nodeXY.setDelta(pointoffsetXY); + } + + if (NodeJson.get("attributes") != null) { + J2735NodeAttributeSet attributeSet = new J2735NodeAttributeSet(); + JsonNode attributes = NodeJson.get("attributes"); + + JsonNode localNode = attributes.get("localNode"); + if (localNode != null) { + JsonNode nodeAttributeXY = localNode.get("NodeAttributeXY"); + if (nodeAttributeXY != null) { + List naList = new ArrayList<>(); + + if (nodeAttributeXY.isArray()) { + Iterator elements = nodeAttributeXY.elements(); + + while (elements.hasNext()) { + String nodeAttributeValue = elements.next().fields().next().getKey(); + naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); + } + } else { + String nodeAttributeValue = nodeAttributeXY.fields().next().getKey(); + naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); + } + + attributeSet.setLocalNode(naList.toArray(new J2735NodeAttribute[0])); + } + } + + JsonNode disabled = attributes.get("disabled"); + if (disabled != null) { + JsonNode segmentAttributeXY = disabled.get("SegmentAttributeXY"); + if (segmentAttributeXY != null) { + List saList = new ArrayList<>(); + + if (segmentAttributeXY.isArray()) { + Iterator elements = segmentAttributeXY.elements(); + + while (elements.hasNext()) { + String segmentAttributeValue = elements.next().fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + } else { + String segmentAttributeValue = segmentAttributeXY.fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + + attributeSet.setDisabled(saList.toArray(new J2735SegmentAttribute[0])); + } + } + + JsonNode enabled = attributes.get("enabled"); + if (enabled != null) { + JsonNode segmentAttributeXY = enabled.get("SegmentAttributeXY"); + if (segmentAttributeXY != null) { + List saList = new ArrayList<>(); + + if (segmentAttributeXY.isArray()) { + Iterator elements = segmentAttributeXY.elements(); + + while (elements.hasNext()) { + String segmentAttributeValue = elements.next().fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + } else { + String segmentAttributeValue = segmentAttributeXY.fields().next().getKey(); + saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); + } + + attributeSet.setEnabled(saList.toArray(new J2735SegmentAttribute[0])); + } + } + + JsonNode data = attributes.get("data"); + if (data != null) { + JsonNode laneDataAttribute = data.get("LaneDataAttribute"); + if (laneDataAttribute != null) { + List ldaList = new ArrayList<>(); + + if (laneDataAttribute.isArray()) { + Iterator elements = laneDataAttribute.elements(); + + while (elements.hasNext()) { + ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(elements.next())); + } + } else { + ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(laneDataAttribute)); + } + + attributeSet.setData(ldaList.toArray(new J2735LaneDataAttribute[0])); + } + } + + if(attributes.get("dWidth") != null) + { + attributeSet.setdWidth(attributes.get("dWidth").asInt()); + } + + if(attributes.get("dElevation") != null) + { + attributeSet.setdElevation(attributes.get("dElevation").asInt()); + } + + nodeXY.setAttributes(attributeSet); + } + return nodeXY; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java new file mode 100644 index 000000000..5fb86c895 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java @@ -0,0 +1,39 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735Offset; +import us.dot.its.jpo.ode.plugin.j2735.J2735OffsetSystem; + +public class OffsetSystemBuilder { + private OffsetSystemBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735OffsetSystem genericOffsetSystem(JsonNode offsetSystem) { + J2735OffsetSystem genericOffsetSystem = new J2735OffsetSystem(); + + JsonNode scale = offsetSystem.get("scale"); + if (scale != null) { + genericOffsetSystem.setScale(scale.asInt()); + } + + JsonNode offset = offsetSystem.get("offset"); + if (offset != null) { + J2735Offset offsetObj = new J2735Offset(); + + JsonNode xy = offset.get("xy"); + JsonNode ll = offset.get("ll"); + + if (xy != null) { + offsetObj.setXY(NodeListXYBuilder.genericNodeListXY(xy)); + } else if (ll != null) { + offsetObj.setLL(NodeListLLBuilder.genericNodeListLL(ll)); + } + + genericOffsetSystem.setOffset(offsetObj); + } + + return genericOffsetSystem; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/Position3DBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/Position3DBuilder.java index 034bef985..7a9b2146b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/Position3DBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/Position3DBuilder.java @@ -36,7 +36,10 @@ private Position3DBuilder() { public static DsrcPosition3D dsrcPosition3D(JsonNode pos) { Long latitude = pos.get("lat").asLong(); Long longitude = pos.get("long").asLong(); - Long elevation = pos.get(ELEVATION).asLong(); + Long elevation = null; + if (pos.get(ELEVATION) != null) { + elevation = pos.get(ELEVATION).asLong(); + } return new DsrcPosition3D(latitude, longitude, elevation); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/RoadSignIdBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/RoadSignIdBuilder.java new file mode 100644 index 000000000..0ec65cca6 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/RoadSignIdBuilder.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.DsrcPosition3D; +import us.dot.its.jpo.ode.plugin.j2735.J2735MutcdCode; +import us.dot.its.jpo.ode.plugin.j2735.J2735RoadSignId; + +public class RoadSignIdBuilder { + private RoadSignIdBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735RoadSignId genericRoadSignId(JsonNode roadSignId) { + J2735RoadSignId genericRoadSignId = new J2735RoadSignId(); + + JsonNode position = roadSignId.get("position"); + if (position != null) { + DsrcPosition3D dsrcPosition3d = Position3DBuilder.dsrcPosition3D(position); + genericRoadSignId.setPosition(Position3DBuilder.odePosition3D(dsrcPosition3d)); + } + + JsonNode viewAngle = roadSignId.get("viewAngle"); + if (viewAngle != null) { + genericRoadSignId.setViewAngle(viewAngle.asText()); + } + + JsonNode mutcdCode = roadSignId.get("mutcdCode"); + if (mutcdCode != null) { + String mutcdCodeValue = mutcdCode.fields().next().getKey(); + genericRoadSignId.setMutcdCode(J2735MutcdCode.valueOf(mutcdCodeValue)); + } + + JsonNode crc = roadSignId.get("crc"); + if (crc != null) { + genericRoadSignId.setCrc(crc.asText()); + } + + return genericRoadSignId; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java new file mode 100644 index 000000000..26bd1a627 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java @@ -0,0 +1,67 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; +import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerDataFrame; + +public class TIMBuilder { + private TIMBuilder() { + throw new UnsupportedOperationException(); + } + + public static J2735Tim genericTim(JsonNode TimMessage) { + J2735Tim genericTim = new J2735Tim(); + + JsonNode msgCnt = TimMessage.get("msgCnt"); + if (msgCnt != null) { + genericTim.setMsgCnt(msgCnt.asText()); + } + + JsonNode timeStamp = TimMessage.get("timeStamp"); + if (timeStamp != null) { + genericTim.setTimeStamp(timeStamp.asText()); + } + + JsonNode packetID = TimMessage.get("packetID"); + if (packetID != null) { + genericTim.setPacketID(packetID.asText()); + } + + // The decoder makes a null URL a literal string value of "null" when it is not specified + JsonNode urlB = TimMessage.get("urlB"); + if (urlB != null) { + String urlBValue = urlB.asText(); + if ("null".equals(urlBValue)) { + urlBValue = null; + } + genericTim.setUrlB(urlBValue); + } + + JsonNode dataFrames = TimMessage.get("dataFrames"); + if (dataFrames != null) { + JsonNode travelerDataFrame = dataFrames.get("TravelerDataFrame"); + if (travelerDataFrame != null) { + List dfList = new ArrayList<>(); + + if (travelerDataFrame.isArray()) { + Iterator elements = travelerDataFrame.elements(); + + while (elements.hasNext()) { + dfList.add(TravelerDataFrameBuilder.genericTravelerDataFrame(elements.next())); + } + } else { + dfList.add(TravelerDataFrameBuilder.genericTravelerDataFrame(travelerDataFrame)); + } + + genericTim.setDataFrames(dfList.toArray(new J2735TravelerDataFrame[0])); + } + } + + return genericTim; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java new file mode 100644 index 000000000..4877874cb --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java @@ -0,0 +1,126 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import us.dot.its.jpo.ode.plugin.j2735.J2735GeographicalPath; +import us.dot.its.jpo.ode.plugin.j2735.J2735MsgId; +import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerDataFrame; +import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerInfoType; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Content; + +public class TravelerDataFrameBuilder { + private TravelerDataFrameBuilder() { + throw new UnsupportedOperationException(); + } + + private final static ObjectMapper mapper = new ObjectMapper(); + + public static J2735TravelerDataFrame genericTravelerDataFrame(JsonNode travelerDataFrame) { + J2735TravelerDataFrame genericTravelerDataFrame = new J2735TravelerDataFrame(); + + JsonNode notUsed = travelerDataFrame.get("notUsed"); + if (notUsed != null) { + genericTravelerDataFrame.setNotUsed(notUsed.asText()); + } + + JsonNode frameType = travelerDataFrame.get("frameType"); + if (frameType != null) { + String frameTypeValue = frameType.fields().next().getKey(); + genericTravelerDataFrame.setFrameType(J2735TravelerInfoType.valueOf(frameTypeValue)); + } + + JsonNode msgId = travelerDataFrame.get("msgId"); + if (msgId != null) { + J2735MsgId msgIdObj = new J2735MsgId(); + + JsonNode furtherInfoID = msgId.get("furtherInfoID"); + if (furtherInfoID != null) { + msgIdObj.setFurtherInfoId(furtherInfoID.asText()); + } + + JsonNode roadSignID = msgId.get("roadSignID"); + if (roadSignID != null) { + msgIdObj.setRoadSignID(RoadSignIdBuilder.genericRoadSignId(roadSignID)); + } + + genericTravelerDataFrame.setMsgId(msgIdObj); + } + + JsonNode startYear = travelerDataFrame.get("startYear"); + if (startYear != null) { + genericTravelerDataFrame.setStartYear(startYear.asText()); + } + + JsonNode startTime = travelerDataFrame.get("startTime"); + if (startTime != null) { + genericTravelerDataFrame.setStartTime(startTime.asText()); + } + + JsonNode durationTime = travelerDataFrame.get("durationTime"); + if (durationTime != null) { + genericTravelerDataFrame.setDurationTime(durationTime.asText()); + } + + JsonNode priority = travelerDataFrame.get("priority"); + if (priority != null) { + genericTravelerDataFrame.setPriority(priority.asText()); + } + + JsonNode notUsed1 = travelerDataFrame.get("notUsed1"); + if (notUsed1 != null) { + genericTravelerDataFrame.setNotUsed1(notUsed1.asText()); + } + + JsonNode regions = travelerDataFrame.get("regions"); + if (regions != null) { + JsonNode geographicalPath = regions.get("GeographicalPath"); + if (geographicalPath != null) { + List gpList = new ArrayList<>(); + + if (geographicalPath.isArray()) { + Iterator elements = geographicalPath.elements(); + + while (elements.hasNext()) { + gpList.add(GeographicalPathBuilder.genericGeographicalPath(elements.next())); + } + } else { + gpList.add(GeographicalPathBuilder.genericGeographicalPath(geographicalPath)); + } + + genericTravelerDataFrame.setRegions(gpList.toArray(new J2735GeographicalPath[0])); + } + } + + JsonNode notUsed2 = travelerDataFrame.get("notUsed2"); + if (notUsed2 != null) { + genericTravelerDataFrame.setNotUsed2(notUsed2.asText()); + } + + JsonNode notUsed3 = travelerDataFrame.get("notUsed3"); + if (notUsed3 != null) { + genericTravelerDataFrame.setNotUsed3(notUsed3.asText()); + } + + JsonNode content = travelerDataFrame.get("content"); + if (content != null) { + genericTravelerDataFrame.setContent(mapper.convertValue(content, Content.class)); + } + + // The decoder makes a null URL a literal string value of "null" when it is not specified + JsonNode url = travelerDataFrame.get("url"); + if (url != null) { + String urlValue = url.asText(); + if ("null".equals(urlValue)) { + urlValue = null; + } + genericTravelerDataFrame.setUrl(urlValue); + } + + return genericTravelerDataFrame; + } +} diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java index e9d81dfa3..04726b71e 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java @@ -20,18 +20,23 @@ import org.junit.jupiter.api.Test; public class J2735DirectionOfUseTest { + @Test + public void checkUnavailable() { + assertNotNull(J2735DirectionOfUse.unavailable); + } + @Test public void checkForward() { - assertNotNull(J2735DirectionOfUse.FORWARD); + assertNotNull(J2735DirectionOfUse.forward); } @Test public void checkReverse() { - assertNotNull(J2735DirectionOfUse.REVERSE); + assertNotNull(J2735DirectionOfUse.reverse); } @Test public void checkBoth() { - assertNotNull(J2735DirectionOfUse.BOTH); + assertNotNull(J2735DirectionOfUse.both); } } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java new file mode 100644 index 000000000..921b0422b --- /dev/null +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; +import us.dot.its.jpo.ode.util.XmlUtils; +import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; + +public class TimBuilderTest { + @Test + public void shouldTranslateTim() { + + JsonNode jsonMap = null; + try { + jsonMap = XmlUtils.toObjectNode( + "timMsgsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload4d476fdf-9103-464d-88c5-5de24b9f3ef910002024-11-21T01:17:47.998Z70RSUfalse001F810A701607988D44FF260FFFD00C010F775D9B0B01C2715BDE59674A61AFFFF93F4310B021C0A007F91A54ED2088C10346A820F2C7A105164CE000000002715BDE59674A61A9388CE00021100CFA9460EE711C707B8C97B45536D12F62A75A8B8E0F329509879F9AF683B375AAC1B8AEAF70D60B3DA000C80218312D11081EEEBB36301C2715DFCC1673BB4FFFFF93F4310B021C0A007F99A54ED2088C10346A820E8CB8722083CB1E8CBC905164CE000000002715DFCC1673BB4F9388C7C0021160A5A4000E1D8955078014AA83CFCA84C1F47D5ED1521A3AF68AAD25DED055B4CF7B42AF9D7D5515A5DBFB40AE11A05EC559B908E42A8888555001A00430601C312D11080D404F775D9B00358C2614C511ABFC4ED8D5830858CC42A5B1B0023B5A84F612289408C096D7DFC084AA26FA6023C7D787B119AC3920090449C099FE4A4DF873D6B46EC2FC98916754931A4C5A500000000134E749ACB3149E209C46003C10B02211F450076888E5258B044869CC2E211098FF7108FC9E41897CCDC1704B9FCE4D42435E7023127413C78893C4DF7E848769083412036397111DCCC1B089CBA66C4435093DE2205BCA4D7089754160D73EF8A0E8441EB237825E3184501296941CB88E972102448D87064A3520F20A170A0350E408AABE263849C0B0D302157C8CC612CE3C3CA893FB247C420300172.18.0.1MessageFrame3113951608D44FF260FFFD00C01null0411472587-104651309811111111111111112024401760864050RSZ D0 45 Arch Q2300411472587-10465130985000011100000000000001274326594491070521517106782427100742958654825796649303457423414362728072821197200268125898720null0411489944-104663331211111111111111112024401760864050RSZ D0 45 Ahead Archer Q2300411489944-1046633312500000111110000000000602-10244332-34146145-34146649-30347455-25799268-257911081-212411686-106212189-68313499-15214406379114841138103761365002681230212589872013569null"); + } catch (XmlUtilsException e) { + fail("XML parsing error:" + e); + } + J2735Tim actualTim = TIMBuilder.genericTim(jsonMap.findValue("TravelerInformation")); + String expected ="{\"msgCnt\":\"1\",\"timeStamp\":\"395160\",\"packetID\":\"8D44FF260FFFD00C01\",\"dataFrames\":[{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Arch Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":true,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1274,\"lat\":326}}},{\"delta\":{\"nodeLL2\":{\"lon\":5944,\"lat\":910}}},{\"delta\":{\"nodeLL2\":{\"lon\":7052,\"lat\":1517}}},{\"delta\":{\"nodeLL3\":{\"lon\":10678,\"lat\":2427}}},{\"delta\":{\"nodeLL3\":{\"lon\":10074,\"lat\":2958}}},{\"delta\":{\"nodeLL2\":{\"lon\":6548,\"lat\":2579}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":5742,\"lat\":3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":3627,\"lat\":2807}}},{\"delta\":{\"nodeLL2\":{\"lon\":2821,\"lat\":1972}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}}]}}},{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Ahead Archer Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":602,\"lat\":-1024}}},{\"delta\":{\"nodeLL2\":{\"lon\":4332,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6145,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":-3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":7455,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":9268,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":11081,\"lat\":-2124}}},{\"delta\":{\"nodeLL3\":{\"lon\":11686,\"lat\":-1062}}},{\"delta\":{\"nodeLL3\":{\"lon\":12189,\"lat\":-683}}},{\"delta\":{\"nodeLL3\":{\"lon\":13499,\"lat\":-152}}},{\"delta\":{\"nodeLL3\":{\"lon\":14406,\"lat\":379}}},{\"delta\":{\"nodeLL3\":{\"lon\":11484,\"lat\":1138}}},{\"delta\":{\"nodeLL3\":{\"lon\":10376,\"lat\":1365}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12302\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}},{\"item\":{\"itis\":\"13569\"}}]}}}]}"; + assertEquals(expected, actualTim.toString()); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java new file mode 100644 index 000000000..41ab2edae --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -0,0 +1,59 @@ +package us.dot.its.jpo.ode.coder; + +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.model.OdeTimData; +import us.dot.its.jpo.ode.model.OdeTimMetadata; +import us.dot.its.jpo.ode.model.OdeTimPayload; +import us.dot.its.jpo.ode.model.ReceivedMessageDetails; +import us.dot.its.jpo.ode.model.RxSource; +import us.dot.its.jpo.ode.plugin.j2735.builders.TIMBuilder; +import us.dot.its.jpo.ode.util.JsonUtils; +import us.dot.its.jpo.ode.util.XmlUtils; +import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; + +public class OdeTimDataCreatorHelper { + + public OdeTimDataCreatorHelper() { + } + + public static OdeTimData createOdeTimData(String consumedData) throws XmlUtilsException { + ObjectNode consumed = XmlUtils.toObjectNode(consumedData); + + JsonNode metadataNode = consumed.findValue(AppContext.METADATA_STRING); + if (metadataNode instanceof ObjectNode) { + ObjectNode object = (ObjectNode) metadataNode; + object.remove(AppContext.ENCODINGS_STRING); + + // Map header file does not have a location and use predefined set required + // RxSource + ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); + receivedMessageDetails.setRxSource(RxSource.NA); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode; + try { + jsonNode = objectMapper.readTree(receivedMessageDetails.toJson()); + object.set(AppContext.RECEIVEDMSGDETAILS_STRING, jsonNode); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + OdeTimMetadata metadata = (OdeTimMetadata) JsonUtils.fromJson(metadataNode.toString(), OdeTimMetadata.class); + + if (metadata.getSchemaVersion() <= 4) { + metadata.setReceivedMessageDetails(null); + } + + OdeTimPayload payload = new OdeTimPayload(TIMBuilder.genericTim(consumed.findValue("TravelerInformation"))); + return new OdeTimData(metadata, payload); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index af8809864..d7e4aea35 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -91,7 +91,7 @@ public Object process(String consumedData) { switch (messageId) { case BasicSafetyMessage -> routeBSM(consumedData, recordType); - case TravelerInformation -> routeTIM(consumed, recordType); + case TravelerInformation -> routeTIM(consumedData, recordType); case SPATMessage -> routeSPAT(consumedData, recordType); case MAPMessage -> routeMAP(consumedData, recordType); case SSMMessage -> routeSSM(consumedData, recordType); @@ -158,8 +158,8 @@ private void routeSPAT(String consumedData, RecordType recordType) throws XmlUti log.debug("Submitted to SPAT Pojo topic {}", jsonTopics.getSpat()); } - private void routeTIM(JSONObject consumed, RecordType recordType) { - String odeTimData = TimTransmogrifier.createOdeTimData(consumed).toString(); + private void routeTIM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { + String odeTimData = OdeTimDataCreatorHelper.createOdeTimData(consumedData).toString(); switch (recordType) { case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); From 5effd8aff539b3ac9a12a2d226860ae6d4bfcc6c Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Sun, 24 Nov 2024 23:54:23 -0700 Subject: [PATCH 065/264] Modify TimCreator to use the new creator. Add and update unit tests --- .../plugin/j2735/builders/ContentBuilder.java | 105 + .../builders/TravelerDataFrameBuilder.java | 6 +- .../plugin/j2735/builders/MAPBuilderTest.java | 27 +- .../plugin/j2735/builders/TimBuilderTest.java | 3 +- .../ode/coder/OdeTimDataCreatorHelper.java | 9 +- .../services/asn1/Asn1DecodedDataRouter.java | 3 +- .../ode/traveler/TimDepositController.java | 48 +- .../jpo/ode/traveler/TimTransmogrifier.java | 14 - .../services/asn1/Asn1CommandManagerTest.java | 1 - .../traveler/TimDepositControllerTest.java | 3 +- .../ode/traveler/TimTransmogrifierTest.java | 13 - ...coderRouter_ApprovalTestCases_MapJson.json | 8554 ++++++++-------- ...derRouter_ApprovalTestCases_MapTxPojo.json | 8566 ++++++++--------- 13 files changed, 8433 insertions(+), 8919 deletions(-) create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ContentBuilder.java diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ContentBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ContentBuilder.java new file mode 100644 index 000000000..1c998705f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/ContentBuilder.java @@ -0,0 +1,105 @@ +package us.dot.its.jpo.ode.plugin.j2735.builders; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.fasterxml.jackson.databind.JsonNode; + +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Content; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.ITIS_CodesAndText; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Items; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.Item; + +public class ContentBuilder { + private ContentBuilder() { + throw new UnsupportedOperationException(); + } + + private static Items genericItems(JsonNode sequence) { + Items itemsObj = new Items(); + + JsonNode item = sequence.get("item"); + if (item != null) { + Item itemObj = new Item(); + + JsonNode itis = item.get("itis"); + if (itis != null) { + itemObj.setItis(itis.asText()); + } + + JsonNode text = item.get("text"); + if (text != null) { + itemObj.setText(text.asText()); + } + + itemsObj.setItem(itemObj); + } + + return itemsObj; + } + + private static Items[] genericSequence(JsonNode contentType) { + Items[] sequenceObj = null; + + JsonNode sequence = contentType.get("SEQUENCE"); + if (sequence != null) { + List iList = new ArrayList<>(); + + if (sequence.isArray()) { + Iterator elements = sequence.elements(); + + while (elements.hasNext()) { + iList.add(genericItems(elements.next())); + } + } else { + iList.add(genericItems(sequence)); + } + + sequenceObj = iList.toArray(new Items[0]); + } + + return sequenceObj; + } + + public static Content genericContent(JsonNode content) { + Content contentObj = new Content(); + + JsonNode advisory = content.get("advisory"); + if (advisory != null) { + ITIS_CodesAndText adivsoryObj = new ITIS_CodesAndText(); + adivsoryObj.setSEQUENCE(genericSequence(advisory)); + contentObj.setAdvisory(adivsoryObj); + } + + JsonNode workZone = content.get("workZone"); + if (workZone != null) { + ITIS_CodesAndText workZoneObj = new ITIS_CodesAndText(); + workZoneObj.setSEQUENCE(genericSequence(workZone)); + contentObj.setWorkZone(workZoneObj); + } + + JsonNode genericSign = content.get("genericSign"); + if (genericSign != null) { + ITIS_CodesAndText genericSignObj = new ITIS_CodesAndText(); + genericSignObj.setSEQUENCE(genericSequence(genericSign)); + contentObj.setGenericSign(genericSignObj); + } + + JsonNode speedLimit = content.get("speedLimit"); + if (speedLimit != null) { + ITIS_CodesAndText speedLimitObj = new ITIS_CodesAndText(); + speedLimitObj.setSEQUENCE(genericSequence(speedLimit)); + contentObj.setSpeedLimit(speedLimitObj); + } + + JsonNode exitService = content.get("exitService"); + if (exitService != null) { + ITIS_CodesAndText exitServiceObj = new ITIS_CodesAndText(); + exitServiceObj.setSEQUENCE(genericSequence(exitService)); + contentObj.setExitService(exitServiceObj); + } + + return contentObj; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java index 4877874cb..290356b0e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java @@ -5,21 +5,17 @@ import java.util.List; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import us.dot.its.jpo.ode.plugin.j2735.J2735GeographicalPath; import us.dot.its.jpo.ode.plugin.j2735.J2735MsgId; import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerDataFrame; import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerInfoType; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.Content; public class TravelerDataFrameBuilder { private TravelerDataFrameBuilder() { throw new UnsupportedOperationException(); } - private final static ObjectMapper mapper = new ObjectMapper(); - public static J2735TravelerDataFrame genericTravelerDataFrame(JsonNode travelerDataFrame) { J2735TravelerDataFrame genericTravelerDataFrame = new J2735TravelerDataFrame(); @@ -108,7 +104,7 @@ public static J2735TravelerDataFrame genericTravelerDataFrame(JsonNode travelerD JsonNode content = travelerDataFrame.get("content"); if (content != null) { - genericTravelerDataFrame.setContent(mapper.convertValue(content, Content.class)); + genericTravelerDataFrame.setContent(ContentBuilder.genericContent(content)); } // The decoder makes a null URL a literal string value of "null" when it is not specified diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java index fd48970dc..3803a9bfc 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java @@ -12,19 +12,18 @@ import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; public class MAPBuilderTest { - @Test - public void shouldTranslateMap() { + @Test + public void shouldTranslateMap() { - JsonNode jsonMap = null; - try { - jsonMap = XmlUtils.toObjectNode( - "us.dot.its.jpo.ode.model.OdeAsn1Payloadd07badec-84f0-48d8-8d4c-898fceaf4ecc10002020-11-30T23:45:24.913657Z60falsemapTxsuccessunsecuredDataMessageFrameUPERV2XMessageFrame184121561389284111-77241071310000000000000000000043244324"); - } catch (XmlUtilsException e) { - fail("XML parsing error:" + e); - } - J2735MAP actualMap = MAPBuilder.genericMAP(jsonMap.findValue("MapData")); - String expected = "{\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\":{\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\":{\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[{\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false,\"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicleTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false,\"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false,\"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false,\"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\":{\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\":false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\":false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}}]}}}]}}]}}"; - System.out.println(actualMap.toJson()); - assertEquals(expected, actualMap.toJson()); - } + JsonNode jsonMap = null; + try { + jsonMap = XmlUtils.toObjectNode( + "us.dot.its.jpo.ode.model.OdeAsn1Payloadd07badec-84f0-48d8-8d4c-898fceaf4ecc10002020-11-30T23:45:24.913657Z60falsemapTxsuccessunsecuredDataMessageFrameUPERV2XMessageFrame184121561389284111-77241071310000000000000000000043244324"); + } catch (XmlUtilsException e) { + fail("XML parsing error:" + e); + } + J2735MAP actualMap = MAPBuilder.genericMAP(jsonMap.findValue("MapData")); + String expected = "{\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\":{\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\":{\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[{\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false,\"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicleTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false,\"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false,\"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false,\"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\":{\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\":false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\":false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\":{\"nodes\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}}]}}]}}]}}"; + assertEquals(expected, actualMap.toJson()); + } } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java index 921b0422b..d62061ee5 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java @@ -23,7 +23,8 @@ public void shouldTranslateTim() { fail("XML parsing error:" + e); } J2735Tim actualTim = TIMBuilder.genericTim(jsonMap.findValue("TravelerInformation")); + String actualTimString = actualTim.toString(); String expected ="{\"msgCnt\":\"1\",\"timeStamp\":\"395160\",\"packetID\":\"8D44FF260FFFD00C01\",\"dataFrames\":[{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Arch Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":true,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1274,\"lat\":326}}},{\"delta\":{\"nodeLL2\":{\"lon\":5944,\"lat\":910}}},{\"delta\":{\"nodeLL2\":{\"lon\":7052,\"lat\":1517}}},{\"delta\":{\"nodeLL3\":{\"lon\":10678,\"lat\":2427}}},{\"delta\":{\"nodeLL3\":{\"lon\":10074,\"lat\":2958}}},{\"delta\":{\"nodeLL2\":{\"lon\":6548,\"lat\":2579}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":5742,\"lat\":3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":3627,\"lat\":2807}}},{\"delta\":{\"nodeLL2\":{\"lon\":2821,\"lat\":1972}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}}]}}},{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Ahead Archer Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":602,\"lat\":-1024}}},{\"delta\":{\"nodeLL2\":{\"lon\":4332,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6145,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":-3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":7455,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":9268,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":11081,\"lat\":-2124}}},{\"delta\":{\"nodeLL3\":{\"lon\":11686,\"lat\":-1062}}},{\"delta\":{\"nodeLL3\":{\"lon\":12189,\"lat\":-683}}},{\"delta\":{\"nodeLL3\":{\"lon\":13499,\"lat\":-152}}},{\"delta\":{\"nodeLL3\":{\"lon\":14406,\"lat\":379}}},{\"delta\":{\"nodeLL3\":{\"lon\":11484,\"lat\":1138}}},{\"delta\":{\"nodeLL3\":{\"lon\":10376,\"lat\":1365}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12302\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}},{\"item\":{\"itis\":\"13569\"}}]}}}]}"; - assertEquals(expected, actualTim.toString()); + assertEquals(expected, actualTimString); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index 41ab2edae..b1ec808f9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimData; import us.dot.its.jpo.ode.model.OdeTimMetadata; import us.dot.its.jpo.ode.model.OdeTimPayload; @@ -23,7 +24,7 @@ public class OdeTimDataCreatorHelper { public OdeTimDataCreatorHelper() { } - public static OdeTimData createOdeTimData(String consumedData) throws XmlUtilsException { + public static OdeTimData createOdeTimDataFromDecoded(String consumedData) throws XmlUtilsException { ObjectNode consumed = XmlUtils.toObjectNode(consumedData); JsonNode metadataNode = consumed.findValue(AppContext.METADATA_STRING); @@ -56,4 +57,10 @@ public static OdeTimData createOdeTimData(String consumedData) throws XmlUtilsEx OdeTimPayload payload = new OdeTimPayload(TIMBuilder.genericTim(consumed.findValue("TravelerInformation"))); return new OdeTimData(metadata, payload); } + + public static OdeTimData createOdeTimDataFromCreator(String consumedData, OdeMsgMetadata metadata) throws XmlUtilsException { + ObjectNode consumed = XmlUtils.toObjectNode(consumedData); + OdeTimPayload payload = new OdeTimPayload(TIMBuilder.genericTim(consumed.findValue("TravelerInformation"))); + return new OdeTimData(metadata, payload); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index d7e4aea35..977a33326 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -26,7 +26,6 @@ import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; -import us.dot.its.jpo.ode.traveler.TimTransmogrifier; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.wrapper.AbstractSubscriberProcessor; import us.dot.its.jpo.ode.wrapper.MessageProducer; @@ -159,7 +158,7 @@ private void routeSPAT(String consumedData, RecordType recordType) throws XmlUti } private void routeTIM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeTimData = OdeTimDataCreatorHelper.createOdeTimData(consumedData).toString(); + String odeTimData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(consumedData).toString(); switch (recordType) { case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 5062017cc..8291b1fee 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -17,12 +17,12 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; -import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; -import us.dot.its.jpo.ode.context.AppContext; + +import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; @@ -44,7 +44,6 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeTimSerializer; -import java.util.UUID; import java.text.ParseException; import java.text.SimpleDateFormat; @@ -87,11 +86,11 @@ public TimDepositControllerException(String errMsg) { @Autowired public TimDepositController(OdeKafkaProperties odeKafkaProperties, - Asn1CoderTopics asn1CoderTopics, - PojoTopics pojoTopics, - JsonTopics jsonTopics, - TimIngestTrackerProperties ingestTrackerProperties, - SecurityServicesProperties securityServicesProperties) { + Asn1CoderTopics asn1CoderTopics, + PojoTopics pojoTopics, + JsonTopics jsonTopics, + TimIngestTrackerProperties ingestTrackerProperties, + SecurityServicesProperties securityServicesProperties) { super(); this.asn1CoderTopics = asn1CoderTopics; @@ -102,7 +101,8 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); - this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducer().getType(), null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); @@ -188,8 +188,8 @@ public synchronized ResponseEntity depositTim(String jsonString, Request try { latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime); + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime); } catch (ParseException e) { log.error("Invalid dateTime parse: ", e); } @@ -217,7 +217,8 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); - // Now that the message has been published to OdeBroadcastTim topic, it should be + // Now that the message has been published to OdeBroadcastTim topic, it should + // be // changed to J2735BroadcastTim serialId timMetadata.setSerialId(serialIdJ2735); @@ -252,21 +253,22 @@ public synchronized ResponseEntity depositTim(String jsonString, Request asd = TimTransmogrifier.buildASD(odeTID.getRequest()); } xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); - log.debug("XML representation: {}", xmlMsg); - JSONObject jsonMsg = XmlUtils.toJSONObject(xmlMsg); + if (xmlMsg != null) { + log.debug("XML representation: {}", xmlMsg); + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); - String j2735Tim = TimTransmogrifier.createOdeTimData(jsonMsg.getJSONObject(AppContext.ODE_ASN1_DATA)) - .toString(); + // Convert XML into ODE TIM JSON object and obfuscate RSU password + OdeTimData odeTimObj = OdeTimDataCreatorHelper.createOdeTimDataFromCreator(xmlMsg, timMetadata); + String j2735Tim = odeTimObj.toString(); + String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); + // publish Broadcast TIM to a J2735 compliant topic. + stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - // publish Broadcast TIM to a J2735 compliant topic. - stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - // publish J2735 TIM also to general un-filtered TIM topic - // with streamID as key - stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); + // publish J2735 TIM also to general un-filtered TIM topic with streamID as key + stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); + } serialIdOde.increment(); serialIdJ2735.increment(); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java index 5ab4561d0..dc7646717 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimTransmogrifier.java @@ -1,7 +1,5 @@ package us.dot.its.jpo.ode.traveler; -import org.json.JSONObject; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -235,16 +233,4 @@ public static JsonNode buildEncodingNode(String name, String type, EncodingRule Asn1Encoding mfEnc = new Asn1Encoding(name, type, rule); return JsonUtils.toObjectNode(mfEnc.toJson()); } - - public static JSONObject createOdeTimData(JSONObject timData) { - - JSONObject metadata = timData.getJSONObject(AppContext.METADATA_STRING); - metadata.put("payloadType", OdeTimPayload.class.getName()); - metadata.remove(AppContext.ENCODINGS_STRING); - - JSONObject payload = timData.getJSONObject(AppContext.PAYLOAD_STRING); - payload.put(AppContext.DATA_TYPE_STRING, TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION); - return timData; - } - } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index 11b152d47..87fd588c9 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -27,7 +27,6 @@ import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeTravelerInputData; import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.security.SecurityServicesProperties; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 5557dcd31..08a0e706e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -195,8 +195,9 @@ public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier captur assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived()); } + // This serves as an integration test without mocking the TimTransmogrifier and XmlUtils @Test - public void testSuccessfulRsuMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { + public void testSuccessfulRsuMessageReturnsSuccessMessagePost() { String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"sspTimRights\": \"1\", \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"sspLocationRights\": \"1\", \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"sspMsgTypes\": \"1\", \"sspMsgContent\": \"1\", \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index acdc24ab1..dbb77beaf 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; -import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; @@ -246,18 +245,6 @@ void testConvertToXMLMessageFrame() assertEquals(expected, actualXML); } - @Test - void testCreateOdeTimData() throws JsonUtilsException { - - JSONObject testObject = JsonUtils - .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); - JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); - - assertEquals( - "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", - actualOdeTimData.toString()); - } - @Test void testConstructorIsPrivate() throws NoSuchMethodException { diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json index b898afd59..7a1d7564c 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json @@ -2,7 +2,7 @@ "cases": [ { "description": "Test Case 1 - MapJson", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadc2010d5f-9ee5-4fef-9242-640e8c17713910002024-11-08T22:01:13.148Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617440366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload85100a89-9411-4bc3-828c-9c398aa829a510002024-11-08T21:38:24.144Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617442366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", "expected": { "metadata": { "logFileName": "", @@ -13,13 +13,13 @@ }, "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", "serialId": { - "streamId": "c2010d5f-9ee5-4fef-9242-640e8c177139", + "streamId": "85100a89-9411-4bc3-828c-9c398aa829a5", "bundleSize": 1, "bundleId": 0, "recordId": 0, "serialNumber": 0 }, - "odeReceivedAt": "2024-11-08T22:01:13.148Z", + "odeReceivedAt": "2024-11-08T21:38:24.144Z", "schemaVersion": 7, "maxDurationTime": 0, "recordGeneratedAt": "", @@ -46,7 +46,7 @@ "refPoint": { "latitude": 39.5948212, "longitude": -104.8830946, - "elevation": "1744.0" + "elevation": 1744.2 }, "laneWidth": 366, "laneSet": { @@ -99,65 +99,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1355, - "y": -1880 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 795, - "y": -2926 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 167, - "y": -2318 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -167, - "y": -1910 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1428, - "y": -7986 - } - }, - "attributes": { - "dElevation": 20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1355, + "y": -1880 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2926 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 167, + "y": -2318 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -167, + "y": -1910 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1428, + "y": -7986 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -272,84 +270,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1004, - "y": -1955 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": 544, - "y": -1765 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 311, - "y": -1853 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": 121, - "y": -1549 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -173, - "y": -1876 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1008, - "y": -5542 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -697, - "y": -3586 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1004, + "y": -1955 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 544, + "y": -1765 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 311, + "y": -1853 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 121, + "y": -1549 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -1876 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1008, + "y": -5542 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -697, + "y": -3586 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -425,59 +421,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 624, - "y": -2010 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 624, + "y": -2010 } - }, - { - "delta": { - "nodeXY6": { - "x": 795, - "y": -2868 - } - }, - "attributes": { - "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2868 } }, - { - "delta": { - "nodeXY6": { - "x": 207, - "y": -2180 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 207, + "y": -2180 } }, - { - "delta": { - "nodeXY6": { - "x": -305, - "y": -2656 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -305, + "y": -2656 } }, - { - "delta": { - "nodeXY6": { - "x": -1590, - "y": -8364 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1590, + "y": -8364 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -553,73 +547,71 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2522, - "y": -1862 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -380, - "y": -981 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": 518, - "y": -2926 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": 35, - "y": -1371 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -161, - "y": -2019 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -677, - "y": -3426 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2522, + "y": -1862 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -380, + "y": -981 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 518, + "y": -2926 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": -1371 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -161, + "y": -2019 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -677, + "y": -3426 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -694,70 +686,68 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1676, - "y": -3102 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1676, + "y": -3102 } }, - { - "delta": { - "nodeXY6": { - "x": -1797, - "y": 608 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1797, + "y": 608 } }, - { - "delta": { - "nodeXY6": { - "x": -4401, - "y": -356 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4401, + "y": -356 } }, - { - "delta": { - "nodeXY6": { - "x": -9504, - "y": -23 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9504, + "y": -23 } }, - { - "delta": { - "nodeXY6": { - "x": -7238, - "y": 39 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -7238, + "y": 39 } - }, - { - "delta": { - "nodeXY6": { - "x": -2171, - "y": -6 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2171, + "y": -6 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -832,29 +822,27 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1517, - "y": -2824 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1517, + "y": -2824 } }, - { - "delta": { - "nodeXY6": { - "x": -1411, - "y": 614 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1411, + "y": 614 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -915,29 +903,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -6816, - "y": -10691 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -6816, + "y": -10691 } }, - { - "delta": { - "nodeXY6": { - "x": -196, - "y": 161 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 161 } } - ] - } + } + ] } }, { @@ -974,29 +960,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -6597, - "y": -10387 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -6597, + "y": -10387 } }, - { - "delta": { - "nodeXY6": { - "x": -207, - "y": 166 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -207, + "y": 166 } } - ] - } + } + ] } }, { @@ -1047,67 +1031,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -664, - "y": -799 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -664, + "y": -799 } - }, - { - "delta": { - "nodeXY6": { - "x": -3525, - "y": -586 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3525, + "y": -586 } }, - { - "delta": { - "nodeXY6": { - "x": -2446, - "y": -225 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2446, + "y": -225 } - }, - { - "delta": { - "nodeXY6": { - "x": -2350, - "y": -138 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2350, + "y": -138 } }, - { - "delta": { - "nodeXY6": { - "x": -8407, - "y": -18 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8407, + "y": -18 } }, - { - "delta": { - "nodeXY6": { - "x": -8513, - "y": 17 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8513, + "y": 17 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1183,62 +1165,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -531, - "y": -1503 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -531, + "y": -1503 } - }, - { - "delta": { - "nodeXY6": { - "x": -2310, - "y": -419 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2310, + "y": -419 } }, - { - "delta": { - "nodeXY6": { - "x": -3646, - "y": -430 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3646, + "y": -430 } }, - { - "delta": { - "nodeXY6": { - "x": -10414, - "y": -143 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10414, + "y": -143 } }, - { - "delta": { - "nodeXY6": { - "x": -9909, - "y": 10 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9909, + "y": 10 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1314,53 +1294,51 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -683, - "y": -1177 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -683, + "y": -1177 } - }, - { - "delta": { - "nodeXY6": { - "x": -3456, - "y": -562 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3456, + "y": -562 } - }, - { - "delta": { - "nodeXY6": { - "x": -2411, - "y": -259 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2411, + "y": -259 } }, - { - "delta": { - "nodeXY6": { - "x": -10834, - "y": -138 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10834, + "y": -138 } - }, - { - "delta": { - "nodeXY6": { - "x": -9372, - "y": 39 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -9372, + "y": 39 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1422,26 +1400,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1538, - "y": -296 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1538, + "y": -296 } - }, - { - "delta": { - "nodeXY6": { - "x": 253, - "y": 63 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 63 } } - ] - } + } + ] } }, { @@ -1478,26 +1454,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1619, - "y": -669 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1619, + "y": -669 } - }, - { - "delta": { - "nodeXY6": { - "x": 265, - "y": 92 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 265, + "y": 92 } } - ] - } + } + ] } }, { @@ -1534,29 +1508,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1757, - "y": -1059 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1757, + "y": -1059 } - }, - { - "delta": { - "nodeXY6": { - "x": 253, - "y": 80 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 80 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -1593,29 +1565,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2269, - "y": 1625 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2269, + "y": 1625 } }, - { - "delta": { - "nodeXY6": { - "x": -311, - "y": -57 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -311, + "y": -57 } } - ] - } + } + ] } }, { @@ -1652,29 +1622,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2200, - "y": 1293 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2200, + "y": 1293 } }, - { - "delta": { - "nodeXY6": { - "x": -334, - "y": -63 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -334, + "y": -63 } } - ] - } + } + ] } }, { @@ -1711,29 +1679,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2108, - "y": 914 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2108, + "y": 914 } }, - { - "delta": { - "nodeXY6": { - "x": -369, - "y": -57 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -369, + "y": -57 } } - ] - } + } + ] } }, { @@ -1770,29 +1736,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2056, - "y": 564 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2056, + "y": 564 } }, - { - "delta": { - "nodeXY6": { - "x": -363, - "y": -69 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -69 } } - ] - } + } + ] } }, { @@ -1829,29 +1793,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1975, - "y": 197 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1975, + "y": 197 } }, - { - "delta": { - "nodeXY6": { - "x": -374, - "y": -80 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -374, + "y": -80 } } - ] - } + } + ] } }, { @@ -1902,37 +1864,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1710, - "y": 2641 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1710, + "y": 2641 } }, - { - "delta": { - "nodeXY6": { - "x": -415, - "y": 2042 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -415, + "y": 2042 } - }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 516 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 516 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2029,40 +1989,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1365, - "y": 2715 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1365, + "y": 2715 } }, - { - "delta": { - "nodeXY6": { - "x": -484, - "y": 2065 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -484, + "y": 2065 } }, - { - "delta": { - "nodeXY6": { - "x": -150, - "y": 528 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -150, + "y": 528 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2124,29 +2082,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -587, - "y": 2813 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -587, + "y": 2813 } }, - { - "delta": { - "nodeXY6": { - "x": -69, - "y": 235 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -69, + "y": 235 } } - ] - } + } + ] } }, { @@ -2197,59 +2153,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 520, - "y": 2310 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 520, + "y": 2310 } }, - { - "delta": { - "nodeXY6": { - "x": 3064, - "y": 643 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3064, + "y": 643 } - }, - { - "delta": { - "nodeXY6": { - "x": 5840, - "y": 889 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5840, + "y": 889 } }, - { - "delta": { - "nodeXY6": { - "x": 3583, - "y": 356 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 356 } - }, - { - "delta": { - "nodeXY6": { - "x": 3329, - "y": 207 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3329, + "y": 207 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2344,51 +2298,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 595, - "y": 1960 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 595, + "y": 1960 } }, - { - "delta": { - "nodeXY6": { - "x": 4642, - "y": 895 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4642, + "y": 895 } - }, - { - "delta": { - "nodeXY6": { - "x": 4953, - "y": 711 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4953, + "y": 711 } }, - { - "delta": { - "nodeXY6": { - "x": 6117, - "y": 516 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 6117, + "y": 516 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2464,75 +2416,73 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 664, - "y": 1620 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 664, + "y": 1620 } }, - { - "delta": { - "nodeXY6": { - "x": 3594, - "y": 677 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3594, + "y": 677 } - }, - { - "delta": { - "nodeXY6": { - "x": 3577, - "y": 574 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3577, + "y": 574 } }, - { - "delta": { - "nodeXY6": { - "x": 2427, - "y": 309 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 2427, + "y": 309 } - }, - { - "delta": { - "nodeXY6": { - "x": 2387, - "y": 246 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2387, + "y": 246 } - }, - { - "delta": { - "nodeXY6": { - "x": 2442, - "y": 172 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2442, + "y": 172 } - }, - { - "delta": { - "nodeXY6": { - "x": 1210, - "y": 80 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 1210, + "y": 80 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2608,59 +2558,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 732, - "y": 1263 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 732, + "y": 1263 } }, - { - "delta": { - "nodeXY6": { - "x": 5921, - "y": 1073 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5921, + "y": 1073 } }, - { - "delta": { - "nodeXY6": { - "x": 3617, - "y": 476 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 476 } - }, - { - "delta": { - "nodeXY6": { - "x": 2422, - "y": 240 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2422, + "y": 240 } - }, - { - "delta": { - "nodeXY6": { - "x": 3631, - "y": 251 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3631, + "y": 251 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2736,53 +2684,51 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 800, - "y": 894 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 800, + "y": 894 } - }, - { - "delta": { - "nodeXY6": { - "x": 3583, - "y": 683 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 683 } - }, - { - "delta": { - "nodeXY6": { - "x": 4735, - "y": 723 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4735, + "y": 723 } - }, - { - "delta": { - "nodeXY6": { - "x": 3617, - "y": 384 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 384 } - }, - { - "delta": { - "nodeXY6": { - "x": 3625, - "y": 249 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3625, + "y": 249 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2844,29 +2790,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 8335, - "y": -222 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 8335, + "y": -222 } }, - { - "delta": { - "nodeXY6": { - "x": 242, - "y": 23 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 23 } } - ] - } + } + ] } } ] @@ -2881,7 +2825,7 @@ }, { "description": "Test Case 2 - MapJson", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadcfc309e0-bcf6-4834-9178-4600d4998b3710002024-11-08T22:01:11.230Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817230366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadcfc309e0-bcf6-4834-9178-4600d4998b3710002024-11-08T22:01:11.230Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817232366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", "expected": { "metadata": { "logFileName": "", @@ -2925,7 +2869,7 @@ "refPoint": { "latitude": 39.5950548, "longitude": -104.8667908, - "elevation": "1723.0" + "elevation": 1723.2 }, "laneWidth": 366, "laneSet": { @@ -2978,40 +2922,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1821, - "y": 1201 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1821, + "y": 1201 } - }, - { - "delta": { - "nodeXY6": { - "x": 22824, - "y": -17 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22824, + "y": -17 } }, - { - "delta": { - "nodeXY6": { - "x": 22927, - "y": -23 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22927, + "y": -23 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3087,40 +3029,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1831, - "y": 833 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1831, + "y": 833 } - }, - { - "delta": { - "nodeXY6": { - "x": 22791, - "y": -39 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22791, + "y": -39 } }, - { - "delta": { - "nodeXY6": { - "x": 22950, - "y": -6 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22950, + "y": -6 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3196,40 +3136,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1839, - "y": 453 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1839, + "y": 453 } - }, - { - "delta": { - "nodeXY6": { - "x": 22869, - "y": 8 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22869, + "y": 8 } }, - { - "delta": { - "nodeXY6": { - "x": 22893, - "y": -12 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22893, + "y": -12 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3305,32 +3243,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2608, - "y": 71 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2608, + "y": 71 } }, - { - "delta": { - "nodeXY6": { - "x": 10503, - "y": 0 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10503, + "y": 0 } + }, + "attributes": { + "dElevation": -60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3406,32 +3342,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2596, - "y": -288 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2596, + "y": -288 } }, - { - "delta": { - "nodeXY6": { - "x": 9697, - "y": 6 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 9697, + "y": 6 } + }, + "attributes": { + "dElevation": -60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3507,32 +3441,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1815, - "y": 1527 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1815, + "y": 1527 } }, - { - "delta": { - "nodeXY6": { - "x": 16128, - "y": 38 - } - }, - "attributes": { - "dElevation": -90 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 16128, + "y": 38 } + }, + "attributes": { + "dElevation": -90 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3613,29 +3545,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1916, - "y": -844 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -844 } }, - { - "delta": { - "nodeXY6": { - "x": 461, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 461, + "y": -6 } } - ] - } + } + ] } }, { @@ -3672,29 +3602,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1916, - "y": -1205 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -1205 } }, - { - "delta": { - "nodeXY6": { - "x": 472, - "y": -6 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 472, + "y": -6 } } - ] - } + } + ] } }, { @@ -3731,29 +3659,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1875, - "y": -1595 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1875, + "y": -1595 } }, - { - "delta": { - "nodeXY6": { - "x": 507, - "y": 0 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 507, + "y": 0 } } - ] - } + } + ] } }, { @@ -3790,29 +3716,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -540, - "y": -2621 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -540, + "y": -2621 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -283 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -283 } } - ] - } + } + ] } }, { @@ -3849,29 +3773,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -888, - "y": -2635 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -888, + "y": -2635 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": -283 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -283 } } - ] - } + } + ] } }, { @@ -3908,29 +3830,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1300, - "y": -2685 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1300, + "y": -2685 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -248 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -248 } } - ] - } + } + ] } }, { @@ -3981,32 +3901,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2089, - "y": -1980 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2089, + "y": -1980 } }, - { - "delta": { - "nodeXY6": { - "x": -11230, - "y": 22 - } - }, - "attributes": { - "dElevation": 70 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -11230, + "y": 22 } + }, + "attributes": { + "dElevation": 70 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4101,40 +4019,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2066, - "y": -1614 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2066, + "y": -1614 } - }, - { - "delta": { - "nodeXY6": { - "x": -22451, - "y": -44 - } - }, - "attributes": { - "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22451, + "y": -44 } }, - { - "delta": { - "nodeXY6": { - "x": -22755, - "y": -14 - } - }, - "attributes": { - "dElevation": 70 + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22755, + "y": -14 } + }, + "attributes": { + "dElevation": 70 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4210,40 +4126,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2041, - "y": -1320 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2041, + "y": -1320 } - }, - { - "delta": { - "nodeXY6": { - "x": -22637, - "y": 29 - } - }, - "attributes": { - "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22637, + "y": 29 } }, - { - "delta": { - "nodeXY6": { - "x": -22601, - "y": 46 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22601, + "y": 46 } + }, + "attributes": { + "dElevation": 60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4319,43 +4233,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2030, - "y": -904 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2030, + "y": -904 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22671, + "y": 3 } }, - { - "delta": { - "nodeXY6": { - "x": -22671, - "y": 3 - } - }, - "attributes": { - "dElevation": 140 + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 18 } }, - { - "delta": { - "nodeXY6": { - "x": -22527, - "y": 18 - } - }, - "attributes": { - "dElevation": 60 - } + "attributes": { + "dElevation": 60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4431,43 +4343,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2430, - "y": -107 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2430, + "y": -107 } }, - { - "delta": { - "nodeXY6": { - "x": -9878, - "y": -11 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9878, + "y": -11 } }, - { - "delta": { - "nodeXY6": { - "x": -2258, - "y": -556 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2258, + "y": -556 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4550,29 +4460,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1939, - "y": 425 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1939, + "y": 425 } }, - { - "delta": { - "nodeXY6": { - "x": -271, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -271, + "y": 0 } } - ] - } + } + ] } }, { @@ -4609,29 +4517,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1916, - "y": 792 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1916, + "y": 792 } }, - { - "delta": { - "nodeXY6": { - "x": -300, - "y": -6 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -300, + "y": -6 } } - ] - } + } + ] } }, { @@ -4668,29 +4574,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1910, - "y": 1154 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1910, + "y": 1154 } }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 } } - ] - } + } + ] } }, { @@ -4727,29 +4631,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1899, - "y": 1504 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1899, + "y": 1504 } }, - { - "delta": { - "nodeXY6": { - "x": -288, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 0 } } - ] - } + } + ] } }, { @@ -4800,95 +4702,93 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -594, - "y": 2467 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -23, - "y": 1503 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": 2249 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -156, - "y": 2008 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -472, - "y": 2163 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -778, - "y": 2323 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1296, - "y": 2209 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1100, - "y": 1549 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -594, + "y": 2467 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": 1503 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 2249 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -156, + "y": 2008 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -778, + "y": 2323 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1296, + "y": 2209 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1100, + "y": 1549 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4964,106 +4864,104 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -997, - "y": 2409 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -12, - "y": 1767 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -105, - "y": 2959 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -153, - "y": 1231 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -420, - "y": 2100 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -824, - "y": 2123 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -674, - "y": 1331 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -755, - "y": 1210 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -835, - "y": 1061 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -997, + "y": 2409 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 1767 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -105, + "y": 2959 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -153, + "y": 1231 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -420, + "y": 2100 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2123 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -674, + "y": 1331 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -755, + "y": 1210 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -835, + "y": 1061 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5179,54 +5077,52 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -288, - "y": 2486 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 2486 } }, - { - "delta": { - "nodeXY6": { - "x": -29, - "y": 3976 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": 3976 } }, - { - "delta": { - "nodeXY6": { - "x": -196, - "y": 1922 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 1922 } }, - { - "delta": { - "nodeXY6": { - "x": -599, - "y": 2473 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -599, + "y": 2473 } + }, + "attributes": { + "dElevation": 20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5302,62 +5198,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 2509 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2509 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 2467 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2467 } }, - { - "delta": { - "nodeXY6": { - "x": -58, - "y": 1979 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -58, + "y": 1979 } - }, - { - "delta": { - "nodeXY6": { - "x": -242, - "y": 1916 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -242, + "y": 1916 } }, - { - "delta": { - "nodeXY6": { - "x": -438, - "y": 1618 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": 1618 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5419,29 +5313,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 442, - "y": 2545 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 442, + "y": 2545 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 333 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 333 } } - ] - } + } + ] } }, { @@ -5478,32 +5370,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 851, - "y": 2533 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 851, + "y": 2533 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 338 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 338 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -5554,32 +5444,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 974, - "y": -2408 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 974, + "y": -2408 } }, - { - "delta": { - "nodeXY6": { - "x": -60, - "y": -15160 - } - }, - "attributes": { - "dElevation": 50 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -60, + "y": -15160 } + }, + "attributes": { + "dElevation": 50 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5655,32 +5543,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 564, - "y": -2467 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 564, + "y": -2467 } }, - { - "delta": { - "nodeXY6": { - "x": -8, - "y": -15094 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8, + "y": -15094 } + }, + "attributes": { + "dElevation": 40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5756,32 +5642,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 202, - "y": -2492 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 202, + "y": -2492 } }, - { - "delta": { - "nodeXY6": { - "x": 10, - "y": -15080 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10, + "y": -15080 } + }, + "attributes": { + "dElevation": 40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5857,32 +5741,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -148, - "y": -2541 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -148, + "y": -2541 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -3031 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -3031 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5958,64 +5840,62 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2555, - "y": -2340 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2555, + "y": -2340 } }, - { - "delta": { - "nodeXY6": { - "x": -357, - "y": -252 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -357, + "y": -252 } - }, - { - "delta": { - "nodeXY6": { - "x": -438, - "y": -459 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": -459 } - }, - { - "delta": { - "nodeXY6": { - "x": -288, - "y": -562 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": -562 } - }, - { - "delta": { - "nodeXY6": { - "x": -177, - "y": -601 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -177, + "y": -601 } - }, - { - "delta": { - "nodeXY6": { - "x": -13, - "y": -9030 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -13, + "y": -9030 } + }, + "attributes": { + "dElevation": 30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6054,7 +5934,7 @@ }, { "description": "Test case 3 - MapJson", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload894cf226-1c88-4e93-8a44-4e2e619593e310002024-11-08T22:01:11.974Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171403663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload894cf226-1c88-4e93-8a44-4e2e619593e310002024-11-08T22:01:11.974Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171463663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", "expected": { "metadata": { "logFileName": "", @@ -6098,7 +5978,7 @@ "refPoint": { "latitude": 39.5950299, "longitude": -104.8404171, - "elevation": "1714.0" + "elevation": 1714.6 }, "laneWidth": 366, "laneSet": { @@ -6151,43 +6031,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2287, - "y": -615 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2287, + "y": -615 } }, - { - "delta": { - "nodeXY6": { - "x": -22396, - "y": -4 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22396, + "y": -4 } }, - { - "delta": { - "nodeXY6": { - "x": -22917, - "y": 155 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22917, + "y": 155 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6263,43 +6141,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2229, - "y": -954 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2229, + "y": -954 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 43 } }, - { - "delta": { - "nodeXY6": { - "x": -22527, - "y": 43 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22850, + "y": 33 } }, - { - "delta": { - "nodeXY6": { - "x": -22850, - "y": 33 - } - }, - "attributes": { - "dElevation": -30 - } + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6375,43 +6251,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2148, - "y": -1384 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2148, + "y": -1384 } }, - { - "delta": { - "nodeXY6": { - "x": -22900, - "y": 37 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22900, + "y": 37 } }, - { - "delta": { - "nodeXY6": { - "x": -22584, - "y": 82 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22584, + "y": 82 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6527,40 +6401,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2431, - "y": 136 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2431, + "y": 136 } }, - { - "delta": { - "nodeXY6": { - "x": -21380, - "y": 63 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -21380, + "y": 63 } }, - { - "delta": { - "nodeXY6": { - "x": -1630, - "y": -321 - } + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1630, + "y": -321 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6643,29 +6515,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2534, - "y": 670 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2534, + "y": 670 } }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 } } - ] - } + } + ] } }, { @@ -6702,32 +6572,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2569, - "y": 1043 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2569, + "y": 1043 } }, - { - "delta": { - "nodeXY6": { - "x": -276, - "y": 0 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -276, + "y": 0 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -6764,32 +6632,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2621, - "y": 1398 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2621, + "y": 1398 } }, - { - "delta": { - "nodeXY6": { - "x": -294, - "y": 11 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -294, + "y": 11 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -6840,32 +6706,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1486, - "y": 2087 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1486, + "y": 2087 } }, - { - "delta": { - "nodeXY6": { - "x": 35, - "y": 6379 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": 6379 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6960,32 +6824,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1158, - "y": 2075 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1158, + "y": 2075 } }, - { - "delta": { - "nodeXY6": { - "x": 63, - "y": 6402 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 63, + "y": 6402 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7061,32 +6923,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -824, - "y": 2052 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2052 } }, - { - "delta": { - "nodeXY6": { - "x": 69, - "y": 6425 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 69, + "y": 6425 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7169,26 +7029,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 242, - "y": 2070 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 2070 } - }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 436 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 436 } } - ] - } + } + ] } }, { @@ -7225,26 +7083,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 645, - "y": 2070 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 645, + "y": 2070 } - }, - { - "delta": { - "nodeXY6": { - "x": -12, - "y": 436 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 436 } } - ] - } + } + ] } }, { @@ -7295,43 +7151,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1947, - "y": 1325 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1947, + "y": 1325 } }, - { - "delta": { - "nodeXY6": { - "x": 22150, - "y": -46 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22150, + "y": -46 } }, - { - "delta": { - "nodeXY6": { - "x": 22325, - "y": -85 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22325, + "y": -85 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7447,43 +7301,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2033, - "y": 1003 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2033, + "y": 1003 } }, - { - "delta": { - "nodeXY6": { - "x": 22028, - "y": -42 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22028, + "y": -42 } }, - { - "delta": { - "nodeXY6": { - "x": 22360, - "y": -105 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22360, + "y": -105 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7559,43 +7411,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2068, - "y": 624 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2068, + "y": 624 } }, - { - "delta": { - "nodeXY6": { - "x": 22029, - "y": -52 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22029, + "y": -52 } }, - { - "delta": { - "nodeXY6": { - "x": 22307, - "y": -72 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22307, + "y": -72 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7671,32 +7521,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2125, - "y": 314 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2125, + "y": 314 } }, - { - "delta": { - "nodeXY6": { - "x": 24076, - "y": -138 - } - }, - "attributes": { - "dElevation": 30 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 24076, + "y": -138 } + }, + "attributes": { + "dElevation": 30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7772,32 +7620,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2183, - "y": -87 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2183, + "y": -87 } }, - { - "delta": { - "nodeXY6": { - "x": 20228, - "y": -69 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 20228, + "y": -69 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7859,29 +7705,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2275, - "y": -661 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2275, + "y": -661 } }, - { - "delta": { - "nodeXY6": { - "x": 282, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 282, + "y": -6 } } - ] - } + } + ] } }, { @@ -7918,29 +7762,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2344, - "y": -1068 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2344, + "y": -1068 } }, - { - "delta": { - "nodeXY6": { - "x": 230, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": -6 } } - ] - } + } + ] } }, { @@ -7977,29 +7819,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2385, - "y": -1395 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2385, + "y": -1395 } }, - { - "delta": { - "nodeXY6": { - "x": 230, - "y": 0 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": 0 } } - ] - } + } + ] } }, { @@ -8050,67 +7890,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 697, - "y": -2067 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 697, + "y": -2067 } - }, - { - "delta": { - "nodeXY6": { - "x": 6, - "y": -4044 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 6, + "y": -4044 } - }, - { - "delta": { - "nodeXY6": { - "x": -173, - "y": -2123 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -2123 } }, - { - "delta": { - "nodeXY6": { - "x": -104, - "y": -929 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -104, + "y": -929 } - }, - { - "delta": { - "nodeXY6": { - "x": -518, - "y": -2708 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -518, + "y": -2708 } }, - { - "delta": { - "nodeXY6": { - "x": -1140, - "y": -4991 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1140, + "y": -4991 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8186,75 +8024,73 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1089, - "y": -2072 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1089, + "y": -2072 } - }, - { - "delta": { - "nodeXY6": { - "x": -29, - "y": -1973 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": -1973 } - }, - { - "delta": { - "nodeXY6": { - "x": -17, - "y": -2593 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -17, + "y": -2593 } - }, - { - "delta": { - "nodeXY6": { - "x": -184, - "y": -1824 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -184, + "y": -1824 } }, - { - "delta": { - "nodeXY6": { - "x": -253, - "y": -1744 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -253, + "y": -1744 } - }, - { - "delta": { - "nodeXY6": { - "x": -363, - "y": -1847 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -1847 } }, - { - "delta": { - "nodeXY6": { - "x": -1146, - "y": -4894 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1146, + "y": -4894 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8349,29 +8185,27 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -12, - "y": -2095 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -12, + "y": -2095 } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": -4222 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": -4222 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8447,67 +8281,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 334, - "y": -2101 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 334, + "y": -2101 } - }, - { - "delta": { - "nodeXY6": { - "x": -23, - "y": -4142 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": -4142 } - }, - { - "delta": { - "nodeXY6": { - "x": -81, - "y": -1411 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -81, + "y": -1411 } }, - { - "delta": { - "nodeXY6": { - "x": -236, - "y": -2042 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -236, + "y": -2042 } - }, - { - "delta": { - "nodeXY6": { - "x": -472, - "y": -2174 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": -2174 } }, - { - "delta": { - "nodeXY6": { - "x": -1112, - "y": -4871 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1112, + "y": -4871 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8569,29 +8401,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -570, - "y": -2153 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -570, + "y": -2153 } }, - { - "delta": { - "nodeXY6": { - "x": -6, - "y": -293 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -6, + "y": -293 } } - ] - } + } + ] } }, { @@ -8628,29 +8458,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1043, - "y": -2153 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1043, + "y": -2153 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": -281 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -281 } } - ] - } + } + ] } } ] @@ -8664,8 +8492,8 @@ } }, { - "description": "Test case 3 - MapJson", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadd71ab23d-0f89-4847-abef-ea6ffe43995b10002024-11-08T22:01:12.973Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689036618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", + "description": "Test case 4 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadd71ab23d-0f89-4847-abef-ea6ffe43995b10002024-11-08T22:01:12.973Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689936618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", "expected": { "metadata": { "logFileName": "", @@ -8709,7 +8537,7 @@ "refPoint": { "latitude": 39.5662624, "longitude": -105.0827211, - "elevation": "1689.0" + "elevation": 1689.9 }, "laneWidth": 366, "laneSet": { @@ -8762,34 +8590,32 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -161, - "y": 1679 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -161, + "y": 1679 } - }, - { - "delta": { - "nodeXY5": { - "x": -14, - "y": 5804 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": -14, + "y": 5804 } - }, - { - "delta": { - "nodeXY4": { - "x": -173, - "y": 2537 - } + } + }, + { + "delta": { + "nodeXY4": { + "x": -173, + "y": 2537 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8865,40 +8691,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -521, - "y": 1709 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -521, + "y": 1709 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 9274 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 9274 } }, - { - "delta": { - "nodeXY4": { - "x": -219, - "y": 3765 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -219, + "y": 3765 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8974,65 +8798,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -840, - "y": 1704 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": 10009 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -12, - "y": 4867 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 218, - "y": 22016 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY6": { - "x": -115, - "y": 9779 - } - }, - "attributes": { - "dElevation": -30 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -840, + "y": 1704 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 10009 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 4867 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 218, + "y": 22016 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -115, + "y": 9779 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9108,65 +8930,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1234, - "y": 1718 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -12, - "y": 7989 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -3, - "y": 8106 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 78, - "y": 24524 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY5": { - "x": -161, - "y": 6037 - } - }, - "attributes": { - "dElevation": -20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1234, + "y": 1718 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 7989 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3, + "y": 8106 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 78, + "y": 24524 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY5": { + "x": -161, + "y": 6037 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9228,26 +9048,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 511, - "y": 1577 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 511, + "y": 1577 } - }, - { - "delta": { - "nodeXY1": { - "x": 17, - "y": 321 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 17, + "y": 321 } } - ] - } + } + ] } }, { @@ -9284,26 +9102,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 926, - "y": 1583 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 926, + "y": 1583 } - }, - { - "delta": { - "nodeXY1": { - "x": 12, - "y": 298 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 12, + "y": 298 } } - ] - } + } + ] } }, { @@ -9354,37 +9170,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1732, - "y": 866 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1732, + "y": 866 } - }, - { - "delta": { - "nodeXY5": { - "x": 6892, - "y": -149 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6892, + "y": -149 } - }, - { - "delta": { - "nodeXY5": { - "x": 5428, - "y": -195 - } - }, - "attributes": { - "dElevation": -20 + } + }, + { + "delta": { + "nodeXY5": { + "x": 5428, + "y": -195 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9460,48 +9274,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1718, - "y": 528 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1718, + "y": 528 } - }, - { - "delta": { - "nodeXY4": { - "x": 3215, - "y": -17 - } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3215, + "y": -17 } - }, - { - "delta": { - "nodeXY5": { - "x": 6091, - "y": -253 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 6091, + "y": -253 } }, - { - "delta": { - "nodeXY4": { - "x": 3008, - "y": -57 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3008, + "y": -57 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9577,34 +9389,32 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1770, - "y": 201 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1770, + "y": 201 } - }, - { - "delta": { - "nodeXY5": { - "x": 4477, - "y": -57 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 4477, + "y": -57 } - }, - { - "delta": { - "nodeXY3": { - "x": 1965, - "y": -57 - } + } + }, + { + "delta": { + "nodeXY3": { + "x": 1965, + "y": -57 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9680,37 +9490,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1735, - "y": -126 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1735, + "y": -126 } - }, - { - "delta": { - "nodeXY5": { - "x": 5584, - "y": -132 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5584, + "y": -132 } - }, - { - "delta": { - "nodeXY4": { - "x": 2507, - "y": 390 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2507, + "y": 390 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9772,26 +9580,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1646, - "y": -621 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1646, + "y": -621 } - }, - { - "delta": { - "nodeXY1": { - "x": 305, - "y": 11 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 305, + "y": 11 } } - ] - } + } + ] } }, { @@ -9828,26 +9634,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1623, - "y": -994 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1623, + "y": -994 } - }, - { - "delta": { - "nodeXY1": { - "x": 317, - "y": 0 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 317, + "y": 0 } } - ] - } + } + ] } }, { @@ -9898,37 +9702,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1908, - "y": -1870 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1908, + "y": -1870 } - }, - { - "delta": { - "nodeXY2": { - "x": -472, - "y": -953 - } + } + }, + { + "delta": { + "nodeXY2": { + "x": -472, + "y": -953 } - }, - { - "delta": { - "nodeXY6": { - "x": -102, - "y": -8773 - } - }, - "attributes": { - "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -102, + "y": -8773 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10003,40 +9805,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 234, - "y": -1688 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 234, + "y": -1688 } - }, - { - "delta": { - "nodeXY5": { - "x": 35, - "y": -6680 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 35, + "y": -6680 } }, - { - "delta": { - "nodeXY4": { - "x": 53, - "y": -3539 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 53, + "y": -3539 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10132,62 +9932,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 578, - "y": -1677 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 578, + "y": -1677 } - }, - { - "delta": { - "nodeXY5": { - "x": 69, - "y": -6709 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 69, + "y": -6709 } }, - { - "delta": { - "nodeXY6": { - "x": 43, - "y": -8790 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 43, + "y": -8790 } }, - { - "delta": { - "nodeXY6": { - "x": 40, - "y": -16478 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 40, + "y": -16478 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": -15152 - } - }, - "attributes": { - "dElevation": -80 + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": -15152 } + }, + "attributes": { + "dElevation": -80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10263,73 +10061,71 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 950, - "y": -1698 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": 63, - "y": -7180 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 12, - "y": -3639 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 40, - "y": -6124 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 103, - "y": -15105 - } - }, - "attributes": { - "dElevation": -50 - } - }, - { - "delta": { - "nodeXY6": { - "x": -46, - "y": -15037 - } - }, - "attributes": { - "dElevation": -80 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 950, + "y": -1698 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 63, + "y": -7180 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 12, + "y": -3639 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 40, + "y": -6124 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 103, + "y": -15105 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -46, + "y": -15037 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10405,40 +10201,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1823, - "y": -12 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1823, + "y": -12 } }, - { - "delta": { - "nodeXY5": { - "x": -5157, - "y": 46 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -5157, + "y": 46 } }, - { - "delta": { - "nodeXY4": { - "x": -2339, - "y": -339 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2339, + "y": -339 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10514,32 +10308,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1817, - "y": -334 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1817, + "y": -334 } }, - { - "delta": { - "nodeXY5": { - "x": -6609, - "y": 29 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6609, + "y": 29 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10615,48 +10407,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1850, - "y": -614 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1850, + "y": -614 } }, - { - "delta": { - "nodeXY5": { - "x": -6045, - "y": -23 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6045, + "y": -23 } }, - { - "delta": { - "nodeXY4": { - "x": -2288, - "y": 172 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2288, + "y": 172 } - }, - { - "delta": { - "nodeXY2": { - "x": -669, - "y": -5 - } + } + }, + { + "delta": { + "nodeXY2": { + "x": -669, + "y": -5 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10732,48 +10522,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1856, - "y": -947 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1856, + "y": -947 } }, - { - "delta": { - "nodeXY5": { - "x": -4644, - "y": -80 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -4644, + "y": -80 } - }, - { - "delta": { - "nodeXY4": { - "x": -3106, - "y": 168 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -3106, + "y": 168 } }, - { - "delta": { - "nodeXY3": { - "x": -1245, - "y": 23 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY3": { + "x": -1245, + "y": 23 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10835,29 +10623,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1829, - "y": 447 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1829, + "y": 447 } }, - { - "delta": { - "nodeXY1": { - "x": -236, - "y": 6 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -236, + "y": 6 } } - ] - } + } + ] } }, { @@ -10894,29 +10680,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1788, - "y": 860 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1788, + "y": 860 } }, - { - "delta": { - "nodeXY1": { - "x": -294, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 } } - ] - } + } + ] } }, { @@ -10953,26 +10737,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1369, - "y": 9302 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1369, + "y": 9302 } - }, - { - "delta": { - "nodeXY1": { - "x": 23, - "y": 505 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 23, + "y": 505 } } - ] - } + } + ] } }, { @@ -11009,26 +10791,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1195, - "y": -1533 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1195, + "y": -1533 } - }, - { - "delta": { - "nodeXY1": { - "x": -29, - "y": -425 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": -29, + "y": -425 } } - ] - } + } + ] } }, { @@ -11065,26 +10845,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -786, - "y": -1510 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -786, + "y": -1510 } - }, - { - "delta": { - "nodeXY1": { - "x": -23, - "y": -448 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": -23, + "y": -448 } } - ] - } + } + ] } }, { @@ -11121,26 +10899,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": 5345, - "y": -1396 - } + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": 5345, + "y": -1396 } - }, - { - "delta": { - "nodeXY1": { - "x": 392, - "y": 17 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 392, + "y": 17 } } - ] - } + } + ] } }, { @@ -11191,48 +10967,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2133, - "y": 1785 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2133, + "y": 1785 } }, - { - "delta": { - "nodeXY2": { - "x": 484, - "y": 895 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 484, + "y": 895 } - }, - { - "delta": { - "nodeXY5": { - "x": 29, - "y": 6979 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 29, + "y": 6979 } }, - { - "delta": { - "nodeXY5": { - "x": 219, - "y": 5992 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 219, + "y": 5992 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11312,29 +11086,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -4894, - "y": 896 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -4894, + "y": 896 } }, - { - "delta": { - "nodeXY1": { - "x": -294, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 } } - ] - } + } + ] } }, { @@ -11371,29 +11143,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -4883, - "y": 540 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -4883, + "y": 540 } }, - { - "delta": { - "nodeXY1": { - "x": -323, - "y": -6 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": -6 } } - ] - } + } + ] } } ] @@ -11407,8 +11177,8 @@ } }, { - "description": "Test case 4 - MapJson", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2c91e8d6-f917-4c82-96e4-9de0da3ddca710002024-11-08T22:01:11.319Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706901702036618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", + "description": "Test case 5 - MapJson", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2c91e8d6-f917-4c82-96e4-9de0da3ddca710002024-11-08T22:01:11.319Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706921702536618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", "expected": { "metadata": { "logFileName": "", @@ -11451,8 +11221,8 @@ "revision": 2, "refPoint": { "latitude": 39.5806913, - "longitude": "-105.0870690", - "elevation": "1702.0" + "longitude": -105.0870692, + "elevation": 1702.5 }, "laneWidth": 366, "laneSet": { @@ -11505,84 +11275,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2121, - "y": 1567 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": -3670, - "y": 7970 - } - }, - "attributes": { - "dElevation": 50 - } - }, - { - "delta": { - "nodeXY4": { - "x": -1195, - "y": 2499 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -1832, - "y": 4149 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4313, - "y": 9347 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4364, - "y": 9515 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4272, - "y": 9547 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2121, + "y": 1567 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -3670, + "y": 7970 + } + }, + "attributes": { + "dElevation": 50 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1195, + "y": 2499 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -1832, + "y": 4149 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4313, + "y": 9347 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4364, + "y": 9515 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4272, + "y": 9547 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11658,81 +11426,79 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1752, - "y": 1601 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": -2218, - "y": 4912 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2662, - "y": 5807 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2581, - "y": 5566 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -3255, - "y": 7046 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -4489, - "y": 9829 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4488, - "y": 9976 - } - }, - "attributes": { - "dElevation": -50 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1752, + "y": 1601 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2218, + "y": 4912 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2662, + "y": 5807 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2581, + "y": 5566 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3255, + "y": 7046 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -4489, + "y": 9829 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4488, + "y": 9976 + } + }, + "attributes": { + "dElevation": -50 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11808,40 +11574,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1313, - "y": 1627 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1313, + "y": 1627 } - }, - { - "delta": { - "nodeXY5": { - "x": -2022, - "y": 4378 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2022, + "y": 4378 } }, - { - "delta": { - "nodeXY4": { - "x": -1194, - "y": 2575 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1194, + "y": 2575 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11917,51 +11681,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -813, - "y": 1649 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -813, + "y": 1649 } - }, - { - "delta": { - "nodeXY5": { - "x": -2201, - "y": 4447 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2201, + "y": 4447 } }, - { - "delta": { - "nodeXY5": { - "x": -3289, - "y": 6358 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3289, + "y": 6358 } }, - { - "delta": { - "nodeXY4": { - "x": -1930, - "y": 3753 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1930, + "y": 3753 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12023,29 +11785,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -191, - "y": 1636 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -191, + "y": 1636 } }, - { - "delta": { - "nodeXY1": { - "x": -127, - "y": 333 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 333 } } - ] - } + } + ] } }, { @@ -12082,29 +11842,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 212, - "y": 1688 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 212, + "y": 1688 } }, - { - "delta": { - "nodeXY1": { - "x": -121, - "y": 350 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -121, + "y": 350 } } - ] - } + } + ] } }, { @@ -12141,29 +11899,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 684, - "y": 1751 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 684, + "y": 1751 } }, - { - "delta": { - "nodeXY1": { - "x": -127, - "y": 298 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 298 } } - ] - } + } + ] } }, { @@ -12214,84 +11970,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 2022, - "y": 816 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 2454, - "y": 0 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 3503, - "y": -172 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 7472, - "y": -293 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 8019, - "y": -63 - } - } - }, - { - "delta": { - "nodeXY4": { - "x": 3405, - "y": 115 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4747, - "y": 310 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 2022, + "y": 816 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2454, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3503, + "y": -172 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 7472, + "y": -293 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8019, + "y": -63 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3405, + "y": 115 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4747, + "y": 310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12367,76 +12121,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 2370, - "y": 498 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4419, - "y": -149 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 8497, - "y": -344 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY4": { - "x": 3531, - "y": -34 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 8106, - "y": 52 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4718, - "y": 316 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 2370, + "y": 498 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4419, + "y": -149 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 8497, + "y": -344 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3531, + "y": -34 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8106, + "y": 52 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4718, + "y": 316 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12512,65 +12264,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3423, - "y": 1969 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY2": { - "x": 236, - "y": 620 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY2": { - "x": -262, - "y": 993 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2057, - "y": 4491 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY4": { - "x": -951, - "y": 2163 - } - }, - "attributes": { - "dElevation": 20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3423, + "y": 1969 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 236, + "y": 620 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": -262, + "y": 993 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2057, + "y": 4491 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY4": { + "x": -951, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12670,26 +12420,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 3219, - "y": -405 - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 3219, + "y": -405 } - }, - { - "delta": { - "nodeXY1": { - "x": 311, - "y": 0 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 311, + "y": 0 } } - ] - } + } + ] } }, { @@ -12726,26 +12474,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 3211, - "y": -1006 - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 3211, + "y": -1006 } - }, - { - "delta": { - "nodeXY1": { - "x": 409, - "y": 6 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 409, + "y": 6 } } - ] - } + } + ] } }, { @@ -12796,51 +12542,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 2729, - "y": -1696 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 2729, + "y": -1696 } }, - { - "delta": { - "nodeXY3": { - "x": 7, - "y": -1089 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY3": { + "x": 7, + "y": -1089 } }, - { - "delta": { - "nodeXY5": { - "x": 2736, - "y": -6046 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2736, + "y": -6046 } }, - { - "delta": { - "nodeXY2": { - "x": 393, - "y": -951 - } + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY2": { + "x": 393, + "y": -951 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12935,40 +12679,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1012, - "y": -1671 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1012, + "y": -1671 } }, - { - "delta": { - "nodeXY5": { - "x": 2845, - "y": -6288 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2845, + "y": -6288 } }, - { - "delta": { - "nodeXY3": { - "x": 904, - "y": -1899 - } + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY3": { + "x": 904, + "y": -1899 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13065,76 +12807,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1430, - "y": -1698 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2767, - "y": -6178 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY5": { - "x": 3194, - "y": -6835 - } - }, - "attributes": { - "dElevation": -30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2990, - "y": -6513 - } - }, - "attributes": { - "dElevation": -40 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5135, - "y": -11024 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5003, - "y": -11021 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1430, + "y": -1698 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2767, + "y": -6178 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3194, + "y": -6835 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2990, + "y": -6513 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5135, + "y": -11024 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5003, + "y": -11021 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13210,76 +12950,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1840, - "y": -1673 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 3318, - "y": -7339 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2599, - "y": -5381 - } - }, - "attributes": { - "dElevation": -30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2407, - "y": -5583 - } - }, - "attributes": { - "dElevation": -40 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5425, - "y": -11583 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5441, - "y": -11713 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1840, + "y": -1673 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3318, + "y": -7339 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2599, + "y": -5381 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2407, + "y": -5583 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5425, + "y": -11583 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5441, + "y": -11713 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13341,32 +13079,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1081, - "y": -1540 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1081, + "y": -1540 } }, - { - "delta": { - "nodeXY1": { - "x": 127, - "y": -310 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 127, + "y": -310 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13403,32 +13139,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -649, - "y": -1528 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -649, + "y": -1528 } }, - { - "delta": { - "nodeXY1": { - "x": 104, - "y": -361 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 104, + "y": -361 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13465,29 +13199,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -234, - "y": -1517 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -234, + "y": -1517 } }, - { - "delta": { - "nodeXY1": { - "x": 98, - "y": -333 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 98, + "y": -333 } } - ] - } + } + ] } }, { @@ -13524,32 +13256,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 238, - "y": -1545 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 238, + "y": -1545 } }, - { - "delta": { - "nodeXY1": { - "x": 92, - "y": -373 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 92, + "y": -373 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13600,54 +13330,52 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2640, - "y": -253 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2640, + "y": -253 } }, - { - "delta": { - "nodeXY6": { - "x": -9828, - "y": -17 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9828, + "y": -17 } }, - { - "delta": { - "nodeXY6": { - "x": -10070, - "y": 57 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10070, + "y": 57 } }, - { - "delta": { - "nodeXY6": { - "x": -9788, - "y": -17 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9788, + "y": -17 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13723,43 +13451,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2452, - "y": -630 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2452, + "y": -630 } }, - { - "delta": { - "nodeXY6": { - "x": -14852, - "y": 46 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -14852, + "y": 46 } }, - { - "delta": { - "nodeXY6": { - "x": -15059, - "y": -11 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -15059, + "y": -11 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13821,29 +13547,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3066, - "y": 1034 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3066, + "y": 1034 } }, - { - "delta": { - "nodeXY1": { - "x": -305, - "y": 0 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -305, + "y": 0 } } - ] - } + } + ] } }, { @@ -13880,32 +13604,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3054, - "y": 644 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3054, + "y": 644 } }, - { - "delta": { - "nodeXY1": { - "x": -323, - "y": 0 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": 0 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13942,29 +13664,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6475, - "y": 1452 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6475, + "y": 1452 } }, - { - "delta": { - "nodeXY1": { - "x": -409, - "y": 0 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -409, + "y": 0 } } - ] - } + } + ] } }, { @@ -14001,29 +13721,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6515, - "y": 1096 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6515, + "y": 1096 } }, - { - "delta": { - "nodeXY1": { - "x": -369, - "y": 0 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -369, + "y": 0 } } - ] - } + } + ] } }, { @@ -14060,29 +13778,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6521, - "y": 752 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6521, + "y": 752 } }, - { - "delta": { - "nodeXY1": { - "x": -363, - "y": -6 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -363, + "y": -6 } } - ] - } + } + ] } } ] diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json index 73ea4019f..e2e47cf4c 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json @@ -2,7 +2,7 @@ "cases": [ { "description": "Test Case 1 - MapTxPojo", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload85100a89-9411-4bc3-828c-9c398aa829a510002024-11-08T21:38:24.144Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617440366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload85100a89-9411-4bc3-828c-9c398aa829a510002024-11-08T21:38:24.144Z70RSUfalse001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.30MessageFrame182088022395948212-104883094617442366229100000000000000000001110000000001355-188010795-292610167-231820-167-191010-1428-79862060100000000008111100000000000819001000000000239100000000000000000000100000000001004-1955544-176510311-185320121-154910-173-187610-1008-554220-697-3586-1050100000000003124910000000000000000000010000000000624-2010795-286820207-218020-305-265620-1590-8364401000000000031218100000000000000000000010000000002522-186210-380-981518-29262035-137110-161-201910-677-342610200010000000001281010000000000000000000001000000000-1676-310220-1797608-10-4401-356-30-9504-2310-723839-2171-6260010000000001271010000000000000000000001000000000-1517-282410-1411614250010000000001251101000000000000000000-6816-1069110-196161261101000000000000000000-6597-1038710-2071663110000000000000000000100000000000-664-799-3525-586-10-2446-225-2350-138-10-8407-1810-85131717100000000000211110000000000000000000100000000000-531-1503-2310-41910-3646-430-20-10414-14310-990910-1019100000000000212110000000000000000000100000000000-683-1177-3456-562-2411-259-10-10834-138-9372391810000000000021176010000000000000000001538-29625363186010000000000000000001619-66926592196010000000000000000001757-105925380108201000000000000000000-22691625-20-311-577201000000000000000000-22001293-20-334-636201000000000000000000-2108914-20-369-575201000000000000000000-2056564-20-363-694201000000000000000000-1975197-20-374-809310000000000000000000001000000000-17102641-20-4152042-28251680010000000004170010000000004210310000000000000000000001000000000-13652715-10-4842065-10-15052860010000000004211401000000000000000000-5872813-10-69235125100000000000000000001010000000005202310-103064643584088910358335633292071081000000000006111001000000000135100000000000000000001000000000005951960-104642895495371110611751610710000000000061145100000000000000000001000000000006641620-10359467735775741024273092387246244217212108010610000000000061155100000000000000000001000000000007321263-1059211073103617476242224036312511051000000000006116510000000000000000000100000000000800894358368347357233617384362524910410000000000061207010000000000000000008335-2221024223", "expected": { "metadata": { "logFileName": "", @@ -46,7 +46,7 @@ "refPoint": { "latitude": 39.5948212, "longitude": -104.8830946, - "elevation": "1744.0" + "elevation": 1744.2 }, "laneWidth": 366, "laneSet": { @@ -99,65 +99,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1355, - "y": -1880 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 795, - "y": -2926 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 167, - "y": -2318 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -167, - "y": -1910 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1428, - "y": -7986 - } - }, - "attributes": { - "dElevation": 20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1355, + "y": -1880 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2926 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 167, + "y": -2318 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -167, + "y": -1910 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1428, + "y": -7986 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -272,84 +270,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1004, - "y": -1955 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": 544, - "y": -1765 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 311, - "y": -1853 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": 121, - "y": -1549 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -173, - "y": -1876 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1008, - "y": -5542 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -697, - "y": -3586 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1004, + "y": -1955 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 544, + "y": -1765 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 311, + "y": -1853 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 121, + "y": -1549 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -1876 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1008, + "y": -5542 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -697, + "y": -3586 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -425,59 +421,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 624, - "y": -2010 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 624, + "y": -2010 } - }, - { - "delta": { - "nodeXY6": { - "x": 795, - "y": -2868 - } - }, - "attributes": { - "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 795, + "y": -2868 } }, - { - "delta": { - "nodeXY6": { - "x": 207, - "y": -2180 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 207, + "y": -2180 } }, - { - "delta": { - "nodeXY6": { - "x": -305, - "y": -2656 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -305, + "y": -2656 } }, - { - "delta": { - "nodeXY6": { - "x": -1590, - "y": -8364 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1590, + "y": -8364 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -553,73 +547,71 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2522, - "y": -1862 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -380, - "y": -981 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": 518, - "y": -2926 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": 35, - "y": -1371 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -161, - "y": -2019 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -677, - "y": -3426 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2522, + "y": -1862 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -380, + "y": -981 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": 518, + "y": -2926 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": -1371 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -161, + "y": -2019 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -677, + "y": -3426 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -694,70 +686,68 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1676, - "y": -3102 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1676, + "y": -3102 } }, - { - "delta": { - "nodeXY6": { - "x": -1797, - "y": 608 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1797, + "y": 608 } }, - { - "delta": { - "nodeXY6": { - "x": -4401, - "y": -356 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4401, + "y": -356 } }, - { - "delta": { - "nodeXY6": { - "x": -9504, - "y": -23 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9504, + "y": -23 } }, - { - "delta": { - "nodeXY6": { - "x": -7238, - "y": 39 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -7238, + "y": 39 } - }, - { - "delta": { - "nodeXY6": { - "x": -2171, - "y": -6 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -2171, + "y": -6 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -832,29 +822,27 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1517, - "y": -2824 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1517, + "y": -2824 } }, - { - "delta": { - "nodeXY6": { - "x": -1411, - "y": 614 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1411, + "y": 614 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -915,29 +903,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -6816, - "y": -10691 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -6816, + "y": -10691 } }, - { - "delta": { - "nodeXY6": { - "x": -196, - "y": 161 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 161 } } - ] - } + } + ] } }, { @@ -974,29 +960,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -6597, - "y": -10387 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -6597, + "y": -10387 } }, - { - "delta": { - "nodeXY6": { - "x": -207, - "y": 166 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -207, + "y": 166 } } - ] - } + } + ] } }, { @@ -1047,67 +1031,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -664, - "y": -799 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -664, + "y": -799 } - }, - { - "delta": { - "nodeXY6": { - "x": -3525, - "y": -586 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3525, + "y": -586 } }, - { - "delta": { - "nodeXY6": { - "x": -2446, - "y": -225 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2446, + "y": -225 } - }, - { - "delta": { - "nodeXY6": { - "x": -2350, - "y": -138 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2350, + "y": -138 } }, - { - "delta": { - "nodeXY6": { - "x": -8407, - "y": -18 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8407, + "y": -18 } }, - { - "delta": { - "nodeXY6": { - "x": -8513, - "y": 17 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8513, + "y": 17 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1183,62 +1165,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -531, - "y": -1503 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -531, + "y": -1503 } - }, - { - "delta": { - "nodeXY6": { - "x": -2310, - "y": -419 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2310, + "y": -419 } }, - { - "delta": { - "nodeXY6": { - "x": -3646, - "y": -430 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -3646, + "y": -430 } }, - { - "delta": { - "nodeXY6": { - "x": -10414, - "y": -143 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10414, + "y": -143 } }, - { - "delta": { - "nodeXY6": { - "x": -9909, - "y": 10 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9909, + "y": 10 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1314,53 +1294,51 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -683, - "y": -1177 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -683, + "y": -1177 } - }, - { - "delta": { - "nodeXY6": { - "x": -3456, - "y": -562 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -3456, + "y": -562 } - }, - { - "delta": { - "nodeXY6": { - "x": -2411, - "y": -259 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2411, + "y": -259 } }, - { - "delta": { - "nodeXY6": { - "x": -10834, - "y": -138 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10834, + "y": -138 } - }, - { - "delta": { - "nodeXY6": { - "x": -9372, - "y": 39 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -9372, + "y": 39 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -1422,26 +1400,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1538, - "y": -296 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1538, + "y": -296 } - }, - { - "delta": { - "nodeXY6": { - "x": 253, - "y": 63 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 63 } } - ] - } + } + ] } }, { @@ -1478,26 +1454,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1619, - "y": -669 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1619, + "y": -669 } - }, - { - "delta": { - "nodeXY6": { - "x": 265, - "y": 92 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 265, + "y": 92 } } - ] - } + } + ] } }, { @@ -1534,29 +1508,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1757, - "y": -1059 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1757, + "y": -1059 } - }, - { - "delta": { - "nodeXY6": { - "x": 253, - "y": 80 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 253, + "y": 80 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -1593,29 +1565,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2269, - "y": 1625 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2269, + "y": 1625 } }, - { - "delta": { - "nodeXY6": { - "x": -311, - "y": -57 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -311, + "y": -57 } } - ] - } + } + ] } }, { @@ -1652,29 +1622,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2200, - "y": 1293 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2200, + "y": 1293 } }, - { - "delta": { - "nodeXY6": { - "x": -334, - "y": -63 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -334, + "y": -63 } } - ] - } + } + ] } }, { @@ -1711,29 +1679,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2108, - "y": 914 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2108, + "y": 914 } }, - { - "delta": { - "nodeXY6": { - "x": -369, - "y": -57 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -369, + "y": -57 } } - ] - } + } + ] } }, { @@ -1770,29 +1736,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2056, - "y": 564 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2056, + "y": 564 } }, - { - "delta": { - "nodeXY6": { - "x": -363, - "y": -69 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -69 } } - ] - } + } + ] } }, { @@ -1829,29 +1793,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1975, - "y": 197 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1975, + "y": 197 } }, - { - "delta": { - "nodeXY6": { - "x": -374, - "y": -80 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -374, + "y": -80 } } - ] - } + } + ] } }, { @@ -1902,37 +1864,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1710, - "y": 2641 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1710, + "y": 2641 } }, - { - "delta": { - "nodeXY6": { - "x": -415, - "y": 2042 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -415, + "y": 2042 } - }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 516 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 516 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2029,40 +1989,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1365, - "y": 2715 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1365, + "y": 2715 } }, - { - "delta": { - "nodeXY6": { - "x": -484, - "y": 2065 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -484, + "y": 2065 } }, - { - "delta": { - "nodeXY6": { - "x": -150, - "y": 528 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -150, + "y": 528 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2124,29 +2082,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -587, - "y": 2813 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -587, + "y": 2813 } }, - { - "delta": { - "nodeXY6": { - "x": -69, - "y": 235 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -69, + "y": 235 } } - ] - } + } + ] } }, { @@ -2197,59 +2153,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 520, - "y": 2310 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 520, + "y": 2310 } }, - { - "delta": { - "nodeXY6": { - "x": 3064, - "y": 643 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3064, + "y": 643 } - }, - { - "delta": { - "nodeXY6": { - "x": 5840, - "y": 889 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5840, + "y": 889 } }, - { - "delta": { - "nodeXY6": { - "x": 3583, - "y": 356 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 356 } - }, - { - "delta": { - "nodeXY6": { - "x": 3329, - "y": 207 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3329, + "y": 207 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2344,51 +2298,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 595, - "y": 1960 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 595, + "y": 1960 } }, - { - "delta": { - "nodeXY6": { - "x": 4642, - "y": 895 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4642, + "y": 895 } - }, - { - "delta": { - "nodeXY6": { - "x": 4953, - "y": 711 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 4953, + "y": 711 } }, - { - "delta": { - "nodeXY6": { - "x": 6117, - "y": 516 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 6117, + "y": 516 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2464,75 +2416,73 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 664, - "y": 1620 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 664, + "y": 1620 } }, - { - "delta": { - "nodeXY6": { - "x": 3594, - "y": 677 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3594, + "y": 677 } - }, - { - "delta": { - "nodeXY6": { - "x": 3577, - "y": 574 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3577, + "y": 574 } }, - { - "delta": { - "nodeXY6": { - "x": 2427, - "y": 309 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 2427, + "y": 309 } - }, - { - "delta": { - "nodeXY6": { - "x": 2387, - "y": 246 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2387, + "y": 246 } - }, - { - "delta": { - "nodeXY6": { - "x": 2442, - "y": 172 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2442, + "y": 172 } - }, - { - "delta": { - "nodeXY6": { - "x": 1210, - "y": 80 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 1210, + "y": 80 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2608,59 +2558,57 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 732, - "y": 1263 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 732, + "y": 1263 } }, - { - "delta": { - "nodeXY6": { - "x": 5921, - "y": 1073 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5921, + "y": 1073 } }, - { - "delta": { - "nodeXY6": { - "x": 3617, - "y": 476 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 476 } - }, - { - "delta": { - "nodeXY6": { - "x": 2422, - "y": 240 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 2422, + "y": 240 } - }, - { - "delta": { - "nodeXY6": { - "x": 3631, - "y": 251 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3631, + "y": 251 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2736,53 +2684,51 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 800, - "y": 894 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 800, + "y": 894 } - }, - { - "delta": { - "nodeXY6": { - "x": 3583, - "y": 683 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3583, + "y": 683 } - }, - { - "delta": { - "nodeXY6": { - "x": 4735, - "y": 723 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 4735, + "y": 723 } - }, - { - "delta": { - "nodeXY6": { - "x": 3617, - "y": 384 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 3617, + "y": 384 } - }, - { - "delta": { - "nodeXY6": { - "x": 3625, - "y": 249 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 3625, + "y": 249 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -2844,29 +2790,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 8335, - "y": -222 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 8335, + "y": -222 } }, - { - "delta": { - "nodeXY6": { - "x": 242, - "y": 23 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 23 } } - ] - } + } + ] } } ] @@ -2881,7 +2825,7 @@ }, { "description": "Test Case 2 - MapTxPojo", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadffadc418-5fcd-43b7-b931-024edc375fae10002024-11-08T22:00:01.224Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817230366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadcfc309e0-bcf6-4834-9178-4600d4998b3710002024-11-08T22:01:11.230Z70RSUfalse001283DA380330002044CA0D4D3EA2D42CC86AFB534E02DC3E5820A80000040000961C7612C5BB250FFDE04DD37663DFFA409D80583C0003009608AA000001000025872783416EC83BFEC81374DD9A67FFA02760160D0000C025824A80000040000961CBE0715BB2AB001004DD3765B5FFD009D80582C0003009609AA00000080000D8A308047027D9B520F000004E202C790000404B0515000000400006C5123F70013ECDA5E1800602710163A8000202581EA80000010000361C5E17DC0A0A6DF8040130134C230E2400118690001080AB100000000D877C7CB4027D8B039AFFF4202CC40000000361DF1ED2C09EC2C0EC3FFD080BB100000000D875379C5027B0B03F70000203B04000000035F791D70C09EC2C003BF72880F4100000000D7C8875B5027B0B0000FDCA203F04000000035EBB1D60C09EC2C003BF8416100A00000040000D77D77844027D9AA845002C052308C7C9000463C40004580228000004000095DFB9E6C9A509AFFA80546349C75FFC80A46058BC00010096010A00000100002578077AD8693C9C00E8152CD27B7802E028F0162D00004025806280000040000B5E049F1E00A0A693B8C00181518D28018012028F0162B00004025808280000020000B5DA09FE540A0A6ACB53FFA81450D772E7DD402828561AA000A02B0E400050210052200000001AF0DB0352050A15FBC6000040188800000006BC42418C0142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800RSU10.11.81.33MessageFrame183088053395950548-104866790817232366165100000000000000000001000000000001821120122824-17-7022927-23-4071000000000006117510000000000000000000100000000000183183322791-39-7022950-6-40610000000000061185100000000000000000001000000000001839453228698-7022893-12-4051000000000006119510000000000000000000010000000000260871-10105030-603001000000000011205100000000000000000000100000000002596-288-1096976-6029010000000000111551000000000000000000000100000000018151527101612838-90140010010000001130010000000002216010000000000000000001916-844-10461-6226010000000000000000001916-1205-20472-6236010000000000000000001875-1595-20507029801000000000000000000-540-2621-207-28330801000000000000000000-888-2635-200-28331801000000000000000000-1300-2685-207-24832110000000000000000000001000000000-2089-1980-10-1123022703100100100000013000100000000021110000000000000000000100000000000-2066-1614-22451-44140-22755-147023100000000000212110000000000000000000100000000000-2041-1320-2263729150-22601466022100000000000213110000000000000000000100000000000-2030-90410-226713140-22527186021100000000000214110000000000000000000010000000000-2430-10710-9878-1140-2258-55610130101000000005114010000000000525201000000000000000000-193942520-27106201000000000000000000-191679220-300-67201000000000000000000-1910115420-28208201000000000000000000-1899150420-288010310000000000000000000100000000000-594246720-23150310-522249-156200810-472216320-778232320-1296220920-110015491029100000000000419310000000000000000000001000000000-997240920-12176710-105295910-153123110-420210010-824212320-674133120-7551210-8351061108001001000000130100000000000437001000000000211310000000000000000000010000000000-288248620-29397610-196192210-5992473202201000000000071123100000000000000000000100000000002325092023246710-581979-242191610-43816181021010100000000711340100000000000000000044225452003331440100000000000000000085125331003381025710000000000000000000100000000000974-2408-30-60-1516050141000000000008126710000000000000000000100000000000564-2467-20-8-1509440131000000000008127710000000000000000000010000000000202-2492-2010-150804060100000000003128710000000000000000000010000000000-148-2541-207-303110501000000000031247100000000000000000000010000000002555-2340-30-357-252-438-459-288-562-177-601-13-903030250010000000001", "expected": { "metadata": { "logFileName": "", @@ -2892,13 +2836,13 @@ }, "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", "serialId": { - "streamId": "ffadc418-5fcd-43b7-b931-024edc375fae", + "streamId": "cfc309e0-bcf6-4834-9178-4600d4998b37", "bundleSize": 1, "bundleId": 0, "recordId": 0, "serialNumber": 0 }, - "odeReceivedAt": "2024-11-08T22:00:01.224Z", + "odeReceivedAt": "2024-11-08T22:01:11.230Z", "schemaVersion": 7, "maxDurationTime": 0, "recordGeneratedAt": "", @@ -2925,7 +2869,7 @@ "refPoint": { "latitude": 39.5950548, "longitude": -104.8667908, - "elevation": "1723.0" + "elevation": 1723.2 }, "laneWidth": 366, "laneSet": { @@ -2978,40 +2922,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1821, - "y": 1201 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1821, + "y": 1201 } - }, - { - "delta": { - "nodeXY6": { - "x": 22824, - "y": -17 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22824, + "y": -17 } }, - { - "delta": { - "nodeXY6": { - "x": 22927, - "y": -23 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22927, + "y": -23 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3087,40 +3029,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1831, - "y": 833 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1831, + "y": 833 } - }, - { - "delta": { - "nodeXY6": { - "x": 22791, - "y": -39 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22791, + "y": -39 } }, - { - "delta": { - "nodeXY6": { - "x": 22950, - "y": -6 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22950, + "y": -6 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3196,40 +3136,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1839, - "y": 453 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1839, + "y": 453 } - }, - { - "delta": { - "nodeXY6": { - "x": 22869, - "y": 8 - } - }, - "attributes": { - "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22869, + "y": 8 } }, - { - "delta": { - "nodeXY6": { - "x": 22893, - "y": -12 - } - }, - "attributes": { - "dElevation": -40 + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22893, + "y": -12 } + }, + "attributes": { + "dElevation": -40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3305,32 +3243,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2608, - "y": 71 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2608, + "y": 71 } }, - { - "delta": { - "nodeXY6": { - "x": 10503, - "y": 0 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10503, + "y": 0 } + }, + "attributes": { + "dElevation": -60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3406,32 +3342,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2596, - "y": -288 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2596, + "y": -288 } }, - { - "delta": { - "nodeXY6": { - "x": 9697, - "y": 6 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 9697, + "y": 6 } + }, + "attributes": { + "dElevation": -60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3507,32 +3441,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1815, - "y": 1527 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1815, + "y": 1527 } }, - { - "delta": { - "nodeXY6": { - "x": 16128, - "y": 38 - } - }, - "attributes": { - "dElevation": -90 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 16128, + "y": 38 } + }, + "attributes": { + "dElevation": -90 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -3613,29 +3545,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1916, - "y": -844 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -844 } }, - { - "delta": { - "nodeXY6": { - "x": 461, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 461, + "y": -6 } } - ] - } + } + ] } }, { @@ -3672,29 +3602,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1916, - "y": -1205 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1916, + "y": -1205 } }, - { - "delta": { - "nodeXY6": { - "x": 472, - "y": -6 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 472, + "y": -6 } } - ] - } + } + ] } }, { @@ -3731,29 +3659,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1875, - "y": -1595 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1875, + "y": -1595 } }, - { - "delta": { - "nodeXY6": { - "x": 507, - "y": 0 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 507, + "y": 0 } } - ] - } + } + ] } }, { @@ -3790,29 +3716,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -540, - "y": -2621 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -540, + "y": -2621 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -283 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -283 } } - ] - } + } + ] } }, { @@ -3849,29 +3773,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -888, - "y": -2635 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -888, + "y": -2635 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": -283 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -283 } } - ] - } + } + ] } }, { @@ -3908,29 +3830,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1300, - "y": -2685 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1300, + "y": -2685 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -248 - } + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -248 } } - ] - } + } + ] } }, { @@ -3981,32 +3901,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2089, - "y": -1980 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2089, + "y": -1980 } }, - { - "delta": { - "nodeXY6": { - "x": -11230, - "y": 22 - } - }, - "attributes": { - "dElevation": 70 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -11230, + "y": 22 } + }, + "attributes": { + "dElevation": 70 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4101,40 +4019,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2066, - "y": -1614 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2066, + "y": -1614 } - }, - { - "delta": { - "nodeXY6": { - "x": -22451, - "y": -44 - } - }, - "attributes": { - "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22451, + "y": -44 } }, - { - "delta": { - "nodeXY6": { - "x": -22755, - "y": -14 - } - }, - "attributes": { - "dElevation": 70 + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22755, + "y": -14 } + }, + "attributes": { + "dElevation": 70 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4210,40 +4126,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2041, - "y": -1320 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2041, + "y": -1320 } - }, - { - "delta": { - "nodeXY6": { - "x": -22637, - "y": 29 - } - }, - "attributes": { - "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22637, + "y": 29 } }, - { - "delta": { - "nodeXY6": { - "x": -22601, - "y": 46 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 150 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22601, + "y": 46 } + }, + "attributes": { + "dElevation": 60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4319,43 +4233,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2030, - "y": -904 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2030, + "y": -904 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22671, + "y": 3 } }, - { - "delta": { - "nodeXY6": { - "x": -22671, - "y": 3 - } - }, - "attributes": { - "dElevation": 140 + "attributes": { + "dElevation": 140 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 18 } }, - { - "delta": { - "nodeXY6": { - "x": -22527, - "y": 18 - } - }, - "attributes": { - "dElevation": 60 - } + "attributes": { + "dElevation": 60 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4431,43 +4343,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2430, - "y": -107 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2430, + "y": -107 } }, - { - "delta": { - "nodeXY6": { - "x": -9878, - "y": -11 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9878, + "y": -11 } }, - { - "delta": { - "nodeXY6": { - "x": -2258, - "y": -556 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY6": { + "x": -2258, + "y": -556 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4550,29 +4460,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1939, - "y": 425 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1939, + "y": 425 } }, - { - "delta": { - "nodeXY6": { - "x": -271, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -271, + "y": 0 } } - ] - } + } + ] } }, { @@ -4609,29 +4517,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1916, - "y": 792 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1916, + "y": 792 } }, - { - "delta": { - "nodeXY6": { - "x": -300, - "y": -6 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -300, + "y": -6 } } - ] - } + } + ] } }, { @@ -4668,29 +4574,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1910, - "y": 1154 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1910, + "y": 1154 } }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 } } - ] - } + } + ] } }, { @@ -4727,29 +4631,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1899, - "y": 1504 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1899, + "y": 1504 } }, - { - "delta": { - "nodeXY6": { - "x": -288, - "y": 0 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 0 } } - ] - } + } + ] } }, { @@ -4800,95 +4702,93 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -594, - "y": 2467 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -23, - "y": 1503 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": 2249 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -156, - "y": 2008 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -472, - "y": 2163 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -778, - "y": 2323 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1296, - "y": 2209 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -1100, - "y": 1549 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -594, + "y": 2467 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": 1503 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 2249 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -156, + "y": 2008 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -778, + "y": 2323 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1296, + "y": 2209 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1100, + "y": 1549 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -4964,106 +4864,104 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -997, - "y": 2409 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -12, - "y": 1767 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -105, - "y": 2959 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -153, - "y": 1231 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -420, - "y": 2100 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -824, - "y": 2123 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -674, - "y": 1331 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -755, - "y": 1210 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -835, - "y": 1061 - } - }, - "attributes": { - "dElevation": 10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -997, + "y": 2409 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 1767 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -105, + "y": 2959 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -153, + "y": 1231 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -420, + "y": 2100 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2123 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -674, + "y": 1331 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -755, + "y": 1210 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -835, + "y": 1061 + } + }, + "attributes": { + "dElevation": 10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5179,54 +5077,52 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -288, - "y": 2486 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -288, + "y": 2486 } }, - { - "delta": { - "nodeXY6": { - "x": -29, - "y": 3976 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": 3976 } }, - { - "delta": { - "nodeXY6": { - "x": -196, - "y": 1922 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -196, + "y": 1922 } }, - { - "delta": { - "nodeXY6": { - "x": -599, - "y": 2473 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -599, + "y": 2473 } + }, + "attributes": { + "dElevation": 20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5302,62 +5198,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 2509 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2509 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 2467 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 2467 } }, - { - "delta": { - "nodeXY6": { - "x": -58, - "y": 1979 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -58, + "y": 1979 } - }, - { - "delta": { - "nodeXY6": { - "x": -242, - "y": 1916 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -242, + "y": 1916 } }, - { - "delta": { - "nodeXY6": { - "x": -438, - "y": 1618 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": 1618 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5419,29 +5313,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 442, - "y": 2545 - } - }, - "attributes": { - "dElevation": 20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 442, + "y": 2545 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 333 - } + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 333 } } - ] - } + } + ] } }, { @@ -5478,32 +5370,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 851, - "y": 2533 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 851, + "y": 2533 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 338 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 338 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -5554,32 +5444,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 974, - "y": -2408 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 974, + "y": -2408 } }, - { - "delta": { - "nodeXY6": { - "x": -60, - "y": -15160 - } - }, - "attributes": { - "dElevation": 50 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -60, + "y": -15160 } + }, + "attributes": { + "dElevation": 50 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5655,32 +5543,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 564, - "y": -2467 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 564, + "y": -2467 } }, - { - "delta": { - "nodeXY6": { - "x": -8, - "y": -15094 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -8, + "y": -15094 } + }, + "attributes": { + "dElevation": 40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5756,32 +5642,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 202, - "y": -2492 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 202, + "y": -2492 } }, - { - "delta": { - "nodeXY6": { - "x": 10, - "y": -15080 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 10, + "y": -15080 } + }, + "attributes": { + "dElevation": 40 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5857,32 +5741,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -148, - "y": -2541 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -148, + "y": -2541 } }, - { - "delta": { - "nodeXY6": { - "x": 7, - "y": -3031 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 7, + "y": -3031 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -5958,64 +5840,62 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2555, - "y": -2340 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2555, + "y": -2340 } }, - { - "delta": { - "nodeXY6": { - "x": -357, - "y": -252 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -357, + "y": -252 } - }, - { - "delta": { - "nodeXY6": { - "x": -438, - "y": -459 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -438, + "y": -459 } - }, - { - "delta": { - "nodeXY6": { - "x": -288, - "y": -562 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -288, + "y": -562 } - }, - { - "delta": { - "nodeXY6": { - "x": -177, - "y": -601 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -177, + "y": -601 } - }, - { - "delta": { - "nodeXY6": { - "x": -13, - "y": -9030 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -13, + "y": -9030 } + }, + "attributes": { + "dElevation": 30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6054,7 +5934,7 @@ }, { "description": "Test case 3 - MapTxPojo", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload6ef718b4-ad04-4260-a9f2-f8c596f0019310002024-11-08T21:52:36.968Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171403663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload894cf226-1c88-4e93-8a44-4e2e619593e310002024-11-08T22:01:11.974Z70RSUfalse00128315380230002044D0094D3EA1DB2CCC713452F402DC325806280000040000B5DC45F6640A0A694423FFE01478D267B809B02788162500004025804280000040000B5DD2DF1180A0A69400C01581478D26BE802102788162700004025802280000050000B5DE71EA600A0A69346401281478D27C88052027889629000040231A2400218C9000196020A00000080002D7681808802829A58F9007E051E15E689FAFC5616A000A02B0C400050210052200000001AEC35053C050515FB9A000040188800000006BAFBC20981414D7EEC800002828401C8800000006BAE1C2BB01414D7EDA800B02828B020D000000200006BD19441381414D802398EB027D8460E48002306200022C093400000200001AF6F5103605053600FE640809F6058D400020096051A00000080000D7CC8880402829B008B323204FB0AC494001C056268000E0420168400000001603CA2058B000103682018840000000160A162058AFFE90368581AA80000050000B61E6E14B409F66EB433FE901428DD7357FAB0294086184800230B20002583C00030196072A00000100002D87F183EB027D9BAC18FFAC050A375D61FE5C0A50058340003009607AA00000100002D88148270027D9BAC1AFF98050A375C8DFEE00A500582C00030096082A00000080000D884D813A027D9BBC18FEEC050F02C690000404B0455000000400006C443BFD4813ECDCF047FBB028281632A0002022024C4000000036238DF5AC09F62C08D3FFD0809B100000000D89287BD4027D8B01CCFFF42028C40000000362545EA3409F62C0734000160B3A00000100008582B977ED2C003381A35FD4DDED40A0A2BFCC3E2FB5F7E9D5B00A0A6BDC63640814140B0C80008012C157400000080014B0882EFD057FE3784B2BFF7BAEFB5FD21E3800A0A2BF81BC9835FA55E3240A0A6BDC336710141423142400118990001160C3A0000008000057FF477D16BFE637C1014140B0550003012C177400000100010B029CEF9657FE96FD26BFD7BD3E8141457F1478066BF143BC101414D7BA86CF902828160C8000602203304000000035F719DE5C0A0A2BFFD3F6D880D4100000000D7BED779702828B0000FDCE813ECCEB0E00B027D858D0FEA2D0476B169636B0200800161F00010022041A400000000BE456B81904002043A400000000BE01114184C00013C457FD24A52058C40001008037263DFF780A146E023C005813EC0A0806012C1554000002000045FE580ADC92E801402829B81AEFFC804FB0281C1804B05950000008000117FBD42371E39FF980A0A6E132C01E813EC0A0606012C18540000010000C780E7B5B3CEA805C0A0A1F0122C8BDCBC0000A0A5F07223204FB028800404B05D5000000400001E02A202DA50180060282814420202000RSU10.11.81.36MessageFrame182088082395950299-1048404171171463663110000000000000000000100000000000-2287-61510-22396-460-22917155-3018100000000000212110000000000000000000100000000000-2229-95410-225274360-2285033-3019100000000000211110000000000000000000101000000000-2148-138410-229003760-2258482-3020100000000000212600100100000022500100000000034110000000000000000000010000000000-243113610-213806360-1630-321110101000000005112010000000000525201000000000000000000-253467010-28206201000000000000000000-2569104310-2760107201000000000000000000-2621139810-29411108310000000000000000000001000000000-1486208710356379-1070010010000001600100000000029310000000000000000000100000000000-1158207510636402-10261000000000004110310000000000000000000010000000000-824205210696425-10180101000000007119010000000000721140100000000000000000024220700436124010000000000000000006452070-124361351000000000000000000010100000000019471325-1022150-462022325-85801200100100000011100100000000027100000000000631451000000000000000000010000000000020331003-1022028-422022360-10580610000000000061155100000000000000000001000000000002068624-1022029-522022307-7280510000000000061165100000000000000000000100000000002125314-1024076-138302601000000000011175100000000000000000000100000000002183-87-1020228-69102501010000000011186010000000000000000002275-661-10282-6196010000000000000000002344-1068-10230-6206010000000000000000002385-1395-10230022710000000000000000000100000000000697-20676-4044-173-212310-104-929-518-270810-1140-4991101210000000000081217100000000000000000000010000000001089-2072-29-1973-17-2593-184-182410-253-1744-363-184710-1146-48941020001001000000119001000000000224710000000000000000000010000000000-12-2095-52-42221050101000000003123710000000000000000000010000000000334-2101-23-4142-81-141110-236-2042-472-217410-1112-48711060100000000003125801000000000000000000-570-215310-6-29326801000000000000000000-1043-2153100-281", "expected": { "metadata": { "logFileName": "", @@ -6065,13 +5945,13 @@ }, "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", "serialId": { - "streamId": "6ef718b4-ad04-4260-a9f2-f8c596f00193", + "streamId": "894cf226-1c88-4e93-8a44-4e2e619593e3", "bundleSize": 1, "bundleId": 0, "recordId": 0, "serialNumber": 0 }, - "odeReceivedAt": "2024-11-08T21:52:36.968Z", + "odeReceivedAt": "2024-11-08T22:01:11.974Z", "schemaVersion": 7, "maxDurationTime": 0, "recordGeneratedAt": "", @@ -6098,7 +5978,7 @@ "refPoint": { "latitude": 39.5950299, "longitude": -104.8404171, - "elevation": "1714.0" + "elevation": 1714.6 }, "laneWidth": 366, "laneSet": { @@ -6151,43 +6031,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2287, - "y": -615 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2287, + "y": -615 } }, - { - "delta": { - "nodeXY6": { - "x": -22396, - "y": -4 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22396, + "y": -4 } }, - { - "delta": { - "nodeXY6": { - "x": -22917, - "y": 155 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22917, + "y": 155 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6263,43 +6141,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2229, - "y": -954 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2229, + "y": -954 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22527, + "y": 43 } }, - { - "delta": { - "nodeXY6": { - "x": -22527, - "y": 43 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22850, + "y": 33 } }, - { - "delta": { - "nodeXY6": { - "x": -22850, - "y": 33 - } - }, - "attributes": { - "dElevation": -30 - } + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6375,43 +6251,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2148, - "y": -1384 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2148, + "y": -1384 } }, - { - "delta": { - "nodeXY6": { - "x": -22900, - "y": 37 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22900, + "y": 37 } }, - { - "delta": { - "nodeXY6": { - "x": -22584, - "y": 82 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -22584, + "y": 82 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6527,40 +6401,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2431, - "y": 136 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2431, + "y": 136 } }, - { - "delta": { - "nodeXY6": { - "x": -21380, - "y": 63 - } - }, - "attributes": { - "dElevation": 60 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -21380, + "y": 63 } }, - { - "delta": { - "nodeXY6": { - "x": -1630, - "y": -321 - } + "attributes": { + "dElevation": 60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1630, + "y": -321 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6643,29 +6515,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2534, - "y": 670 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2534, + "y": 670 } }, - { - "delta": { - "nodeXY6": { - "x": -282, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -282, + "y": 0 } } - ] - } + } + ] } }, { @@ -6702,32 +6572,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2569, - "y": 1043 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2569, + "y": 1043 } }, - { - "delta": { - "nodeXY6": { - "x": -276, - "y": 0 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -276, + "y": 0 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -6764,32 +6632,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -2621, - "y": 1398 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -2621, + "y": 1398 } }, - { - "delta": { - "nodeXY6": { - "x": -294, - "y": 11 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -294, + "y": 11 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] } }, { @@ -6840,32 +6706,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1486, - "y": 2087 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1486, + "y": 2087 } }, - { - "delta": { - "nodeXY6": { - "x": 35, - "y": 6379 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 35, + "y": 6379 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -6960,32 +6824,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1158, - "y": 2075 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1158, + "y": 2075 } }, - { - "delta": { - "nodeXY6": { - "x": 63, - "y": 6402 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 63, + "y": 6402 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7061,32 +6923,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -824, - "y": 2052 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -824, + "y": 2052 } }, - { - "delta": { - "nodeXY6": { - "x": 69, - "y": 6425 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 69, + "y": 6425 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7169,26 +7029,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 242, - "y": 2070 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 242, + "y": 2070 } - }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": 436 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": 436 } } - ] - } + } + ] } }, { @@ -7225,26 +7083,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 645, - "y": 2070 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 645, + "y": 2070 } - }, - { - "delta": { - "nodeXY6": { - "x": -12, - "y": 436 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -12, + "y": 436 } } - ] - } + } + ] } }, { @@ -7295,43 +7151,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1947, - "y": 1325 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1947, + "y": 1325 } }, - { - "delta": { - "nodeXY6": { - "x": 22150, - "y": -46 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22150, + "y": -46 } }, - { - "delta": { - "nodeXY6": { - "x": 22325, - "y": -85 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22325, + "y": -85 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7447,43 +7301,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2033, - "y": 1003 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2033, + "y": 1003 } }, - { - "delta": { - "nodeXY6": { - "x": 22028, - "y": -42 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22028, + "y": -42 } }, - { - "delta": { - "nodeXY6": { - "x": 22360, - "y": -105 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22360, + "y": -105 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7559,43 +7411,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2068, - "y": 624 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2068, + "y": 624 } }, - { - "delta": { - "nodeXY6": { - "x": 22029, - "y": -52 - } - }, - "attributes": { - "dElevation": 20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22029, + "y": -52 } }, - { - "delta": { - "nodeXY6": { - "x": 22307, - "y": -72 - } - }, - "attributes": { - "dElevation": 80 + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 22307, + "y": -72 } + }, + "attributes": { + "dElevation": 80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7671,32 +7521,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2125, - "y": 314 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2125, + "y": 314 } }, - { - "delta": { - "nodeXY6": { - "x": 24076, - "y": -138 - } - }, - "attributes": { - "dElevation": 30 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 24076, + "y": -138 } + }, + "attributes": { + "dElevation": 30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7772,32 +7620,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2183, - "y": -87 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2183, + "y": -87 } }, - { - "delta": { - "nodeXY6": { - "x": 20228, - "y": -69 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 20228, + "y": -69 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -7859,29 +7705,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2275, - "y": -661 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2275, + "y": -661 } }, - { - "delta": { - "nodeXY6": { - "x": 282, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 282, + "y": -6 } } - ] - } + } + ] } }, { @@ -7918,29 +7762,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2344, - "y": -1068 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2344, + "y": -1068 } }, - { - "delta": { - "nodeXY6": { - "x": 230, - "y": -6 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": -6 } } - ] - } + } + ] } }, { @@ -7977,29 +7819,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 2385, - "y": -1395 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 2385, + "y": -1395 } }, - { - "delta": { - "nodeXY6": { - "x": 230, - "y": 0 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 230, + "y": 0 } } - ] - } + } + ] } }, { @@ -8050,67 +7890,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 697, - "y": -2067 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 697, + "y": -2067 } - }, - { - "delta": { - "nodeXY6": { - "x": 6, - "y": -4044 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": 6, + "y": -4044 } - }, - { - "delta": { - "nodeXY6": { - "x": -173, - "y": -2123 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -173, + "y": -2123 } }, - { - "delta": { - "nodeXY6": { - "x": -104, - "y": -929 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -104, + "y": -929 } - }, - { - "delta": { - "nodeXY6": { - "x": -518, - "y": -2708 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -518, + "y": -2708 } }, - { - "delta": { - "nodeXY6": { - "x": -1140, - "y": -4991 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1140, + "y": -4991 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8186,75 +8024,73 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1089, - "y": -2072 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1089, + "y": -2072 } - }, - { - "delta": { - "nodeXY6": { - "x": -29, - "y": -1973 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -29, + "y": -1973 } - }, - { - "delta": { - "nodeXY6": { - "x": -17, - "y": -2593 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -17, + "y": -2593 } - }, - { - "delta": { - "nodeXY6": { - "x": -184, - "y": -1824 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -184, + "y": -1824 } }, - { - "delta": { - "nodeXY6": { - "x": -253, - "y": -1744 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -253, + "y": -1744 } - }, - { - "delta": { - "nodeXY6": { - "x": -363, - "y": -1847 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -363, + "y": -1847 } }, - { - "delta": { - "nodeXY6": { - "x": -1146, - "y": -4894 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1146, + "y": -4894 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8349,29 +8185,27 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -12, - "y": -2095 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -12, + "y": -2095 } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": -4222 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": -4222 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8447,67 +8281,65 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 334, - "y": -2101 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 334, + "y": -2101 } - }, - { - "delta": { - "nodeXY6": { - "x": -23, - "y": -4142 - } + } + }, + { + "delta": { + "nodeXY6": { + "x": -23, + "y": -4142 } - }, - { - "delta": { - "nodeXY6": { - "x": -81, - "y": -1411 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -81, + "y": -1411 } }, - { - "delta": { - "nodeXY6": { - "x": -236, - "y": -2042 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -236, + "y": -2042 } - }, - { - "delta": { - "nodeXY6": { - "x": -472, - "y": -2174 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -472, + "y": -2174 } }, - { - "delta": { - "nodeXY6": { - "x": -1112, - "y": -4871 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -1112, + "y": -4871 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8569,29 +8401,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -570, - "y": -2153 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -570, + "y": -2153 } }, - { - "delta": { - "nodeXY6": { - "x": -6, - "y": -293 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -6, + "y": -293 } } - ] - } + } + ] } }, { @@ -8628,29 +8458,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": -1043, - "y": -2153 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": -1043, + "y": -2153 } }, - { - "delta": { - "nodeXY6": { - "x": 0, - "y": -281 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 0, + "y": -281 } } - ] - } + } + ] } } ] @@ -8664,8 +8492,8 @@ } }, { - "description": "Test case 3 - MapTxPojo", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload3cfe36c5-8cbc-43f3-af8f-a148520df6d910002024-11-08T21:52:39.971Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689036618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", + "description": "Test case 4 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payloadd71ab23d-0f89-4847-abef-ea6ffe43995b10002024-11-08T22:01:12.973Z70RSUfalse0012830538023000205EA2094D3A3E202CA7783451FA02DC385824E8000002000089D7FA3C8FF96D5837A9E7A4163680002025822E80000020000A97DFAB40A0A6C00BD21D013EC3792FAD4163880002025820E80000040001A92E3AA00A0A6BFE6538C813ECC7FD3303027D9B01B5AC0004E235FE3698CC09E2058240003009607BA00000100006A32EEB6028298FFA7E6A04FB31FFDFEA809F66C0276FE601374C7D7F795027B0160B0000C0220270400000000A7FF8A4108E8220290400000000AE7B8BC106654582F6800000400008BB12D889D763ED6CD4D1F3D027B01617000100258316800000400010BADA8407C8F7F7B37CB7C0C09F65EF01F8E04FB02C2A0002004B066D0000004000117754649317D7F1C5F5AF8E0B0540003012C1AB4000001000045D8EF044D741F7C5E72E30C04FB02C110000C04406F08000000017372C9833182C4073080000000172BA0F033D800B07B90000002000117BA05905140476BFCD2EDD813D8031D200012C03140000010000451D42D0C808C5E8027D97035116813EC2B0A4000501485A000296010A000001000062A421736408A2E5813ECD802B5DAA027B1B00507F4404E736005D134009B00589C00010096008A000001000082BB615E6407E1FA013ECB806072409F66405040A013ECD806744FF02739AFFA48A8604D802C520000804B024D000000400015070BFA01414C2F6E02E0282866DD75682C4D0001C04B020D000000400005073B5901414C18BE01D0282816288000E02580E680000040001283196680A0A610C6FF481414338842B0258DFD82C6E0001004B018D0000008000250602268141443771FB058F7A150050508C8E05C1639000080220148400000002836E6FC0A0A0229030805A100000000A104B5C0282806D400202B240000000161566915810BFF2400A48000000008D5480C0F18AE4008480000000093B88680F4880203BA40000000134E16A301C4422581CC800000100012CF576F9028283793BFB201DED0C09F6241B7BB408C3480004218400201AA4000000030CE28E000A0A01B50008062900000000C33B621C0282805EBF400002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B000080200RSU10.11.81.19MessageFrame1820121132395662624-10508272111689936618710000000000000000000010000000000-1611679-145804-1732537270100000000001117710000000000000000000010000000000-521170910239274-10-2193765280100000000001116710000000000000000000100000000000-840170410-5210009-10-124867-1021822016-60-1159779-3041000000000006115710000000000000000000100000000000-1234171810-127989-10-38106-107824524-70-1616037-20510000000000061198010000000000000000005111577173212080100000000000000000092615831229823111000000000000000000010000000000017328666892-1495428-195-20111000000000008124111000000000000000000010000000000017185283215-176091-253-103008-57-10101000000000008125111000000000000000000001000000000017702014477-571965-575010000000000312611100000000000000000000100000000001735-1265584-1322507390-104010000000000312712010000000000000000001646-621305112812010000000000000000001623-99431703014100000000000000000000010000000001908-1870-472-953-102-8773-202900100000000013110000000000000000000010000000000234-168835-6680-1053-3539-1010010000000000511101000000000052110000000000000000000100000000000578-167769-6709-1043-8790-2040-16478-5023-15152-8019100000000000211110000000000000000000100000000000950-169863-7180-1012-3639-1040-6124-10103-15105-50-46-15037-8020100000000000219310000000000000000000010000000000-1823-1210-51574610-2339-33919010000000000718310000000000000000000010000000000-1817-33410-6609291020010000000000717310000000000000000000100000000000-1850-61410-6045-2310-2288172-669-527100000000000416310000000000000000000100000000000-1856-94710-4644-80-310616810-124523281000000000004110401000000000000000000-182944710-236611401000000000000000000-178886010-29402190100000000000000000013699302235055210000000000000000000-1195-1533-29-4254210000000000000000000-786-1510-23-4482913010000000000000000005345-13963921714610000000000000000000001000000000-2133178510484895296979-1021959921300100000000011200100000000013501000000000000000000-489489610-294012501000000000000000000-488354010-323-6", "expected": { "metadata": { "logFileName": "", @@ -8676,13 +8504,13 @@ }, "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", "serialId": { - "streamId": "3cfe36c5-8cbc-43f3-af8f-a148520df6d9", + "streamId": "d71ab23d-0f89-4847-abef-ea6ffe43995b", "bundleSize": 1, "bundleId": 0, "recordId": 0, "serialNumber": 0 }, - "odeReceivedAt": "2024-11-08T21:52:39.971Z", + "odeReceivedAt": "2024-11-08T22:01:12.973Z", "schemaVersion": 7, "maxDurationTime": 0, "recordGeneratedAt": "", @@ -8709,7 +8537,7 @@ "refPoint": { "latitude": 39.5662624, "longitude": -105.0827211, - "elevation": "1689.0" + "elevation": 1689.9 }, "laneWidth": 366, "laneSet": { @@ -8762,34 +8590,32 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -161, - "y": 1679 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -161, + "y": 1679 } - }, - { - "delta": { - "nodeXY5": { - "x": -14, - "y": 5804 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": -14, + "y": 5804 } - }, - { - "delta": { - "nodeXY4": { - "x": -173, - "y": 2537 - } + } + }, + { + "delta": { + "nodeXY4": { + "x": -173, + "y": 2537 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8865,40 +8691,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -521, - "y": 1709 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -521, + "y": 1709 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": 9274 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": 9274 } }, - { - "delta": { - "nodeXY4": { - "x": -219, - "y": 3765 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -219, + "y": 3765 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -8974,65 +8798,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -840, - "y": 1704 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -52, - "y": 10009 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -12, - "y": 4867 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 218, - "y": 22016 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY6": { - "x": -115, - "y": 9779 - } - }, - "attributes": { - "dElevation": -30 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -840, + "y": 1704 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -52, + "y": 10009 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 4867 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 218, + "y": 22016 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY6": { + "x": -115, + "y": 9779 + } + }, + "attributes": { + "dElevation": -30 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9108,65 +8930,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1234, - "y": 1718 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -12, - "y": 7989 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -3, - "y": 8106 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 78, - "y": 24524 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY5": { - "x": -161, - "y": 6037 - } - }, - "attributes": { - "dElevation": -20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1234, + "y": 1718 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -12, + "y": 7989 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3, + "y": 8106 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 78, + "y": 24524 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY5": { + "x": -161, + "y": 6037 + } + }, + "attributes": { + "dElevation": -20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9228,26 +9048,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 511, - "y": 1577 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 511, + "y": 1577 } - }, - { - "delta": { - "nodeXY1": { - "x": 17, - "y": 321 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 17, + "y": 321 } } - ] - } + } + ] } }, { @@ -9284,26 +9102,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 926, - "y": 1583 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 926, + "y": 1583 } - }, - { - "delta": { - "nodeXY1": { - "x": 12, - "y": 298 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 12, + "y": 298 } } - ] - } + } + ] } }, { @@ -9354,37 +9170,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1732, - "y": 866 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1732, + "y": 866 } - }, - { - "delta": { - "nodeXY5": { - "x": 6892, - "y": -149 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 6892, + "y": -149 } - }, - { - "delta": { - "nodeXY5": { - "x": 5428, - "y": -195 - } - }, - "attributes": { - "dElevation": -20 + } + }, + { + "delta": { + "nodeXY5": { + "x": 5428, + "y": -195 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9460,48 +9274,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1718, - "y": 528 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1718, + "y": 528 } - }, - { - "delta": { - "nodeXY4": { - "x": 3215, - "y": -17 - } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3215, + "y": -17 } - }, - { - "delta": { - "nodeXY5": { - "x": 6091, - "y": -253 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 6091, + "y": -253 } }, - { - "delta": { - "nodeXY4": { - "x": 3008, - "y": -57 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3008, + "y": -57 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9577,34 +9389,32 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1770, - "y": 201 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1770, + "y": 201 } - }, - { - "delta": { - "nodeXY5": { - "x": 4477, - "y": -57 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 4477, + "y": -57 } - }, - { - "delta": { - "nodeXY3": { - "x": 1965, - "y": -57 - } + } + }, + { + "delta": { + "nodeXY3": { + "x": 1965, + "y": -57 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9680,37 +9490,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1735, - "y": -126 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1735, + "y": -126 } - }, - { - "delta": { - "nodeXY5": { - "x": 5584, - "y": -132 - } + } + }, + { + "delta": { + "nodeXY5": { + "x": 5584, + "y": -132 } - }, - { - "delta": { - "nodeXY4": { - "x": 2507, - "y": 390 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2507, + "y": 390 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -9772,26 +9580,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1646, - "y": -621 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1646, + "y": -621 } - }, - { - "delta": { - "nodeXY1": { - "x": 305, - "y": 11 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 305, + "y": 11 } } - ] - } + } + ] } }, { @@ -9828,26 +9634,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1623, - "y": -994 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1623, + "y": -994 } - }, - { - "delta": { - "nodeXY1": { - "x": 317, - "y": 0 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 317, + "y": 0 } } - ] - } + } + ] } }, { @@ -9898,37 +9702,35 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1908, - "y": -1870 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1908, + "y": -1870 } - }, - { - "delta": { - "nodeXY2": { - "x": -472, - "y": -953 - } + } + }, + { + "delta": { + "nodeXY2": { + "x": -472, + "y": -953 } - }, - { - "delta": { - "nodeXY6": { - "x": -102, - "y": -8773 - } - }, - "attributes": { - "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -102, + "y": -8773 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10003,40 +9805,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 234, - "y": -1688 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 234, + "y": -1688 } - }, - { - "delta": { - "nodeXY5": { - "x": 35, - "y": -6680 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 35, + "y": -6680 } }, - { - "delta": { - "nodeXY4": { - "x": 53, - "y": -3539 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 53, + "y": -3539 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10132,62 +9932,60 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 578, - "y": -1677 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 578, + "y": -1677 } - }, - { - "delta": { - "nodeXY5": { - "x": 69, - "y": -6709 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 69, + "y": -6709 } }, - { - "delta": { - "nodeXY6": { - "x": 43, - "y": -8790 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 43, + "y": -8790 } }, - { - "delta": { - "nodeXY6": { - "x": 40, - "y": -16478 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": 40, + "y": -16478 } }, - { - "delta": { - "nodeXY6": { - "x": 23, - "y": -15152 - } - }, - "attributes": { - "dElevation": -80 + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": 23, + "y": -15152 } + }, + "attributes": { + "dElevation": -80 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10263,73 +10061,71 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 950, - "y": -1698 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": 63, - "y": -7180 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 12, - "y": -3639 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 40, - "y": -6124 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 103, - "y": -15105 - } - }, - "attributes": { - "dElevation": -50 - } - }, - { - "delta": { - "nodeXY6": { - "x": -46, - "y": -15037 - } - }, - "attributes": { - "dElevation": -80 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 950, + "y": -1698 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": 63, + "y": -7180 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 12, + "y": -3639 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 40, + "y": -6124 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 103, + "y": -15105 + } + }, + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -46, + "y": -15037 + } + }, + "attributes": { + "dElevation": -80 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10405,40 +10201,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1823, - "y": -12 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1823, + "y": -12 } }, - { - "delta": { - "nodeXY5": { - "x": -5157, - "y": 46 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -5157, + "y": 46 } }, - { - "delta": { - "nodeXY4": { - "x": -2339, - "y": -339 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2339, + "y": -339 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10514,32 +10308,30 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1817, - "y": -334 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1817, + "y": -334 } }, - { - "delta": { - "nodeXY5": { - "x": -6609, - "y": 29 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6609, + "y": 29 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10615,48 +10407,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1850, - "y": -614 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1850, + "y": -614 } }, - { - "delta": { - "nodeXY5": { - "x": -6045, - "y": -23 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -6045, + "y": -23 } }, - { - "delta": { - "nodeXY4": { - "x": -2288, - "y": 172 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -2288, + "y": 172 } - }, - { - "delta": { - "nodeXY2": { - "x": -669, - "y": -5 - } + } + }, + { + "delta": { + "nodeXY2": { + "x": -669, + "y": -5 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10732,48 +10522,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1856, - "y": -947 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1856, + "y": -947 } }, - { - "delta": { - "nodeXY5": { - "x": -4644, - "y": -80 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -4644, + "y": -80 } - }, - { - "delta": { - "nodeXY4": { - "x": -3106, - "y": 168 - } - }, - "attributes": { - "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": -3106, + "y": 168 } }, - { - "delta": { - "nodeXY3": { - "x": -1245, - "y": 23 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY3": { + "x": -1245, + "y": 23 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -10835,29 +10623,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1829, - "y": 447 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1829, + "y": 447 } }, - { - "delta": { - "nodeXY1": { - "x": -236, - "y": 6 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -236, + "y": 6 } } - ] - } + } + ] } }, { @@ -10894,29 +10680,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1788, - "y": 860 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1788, + "y": 860 } }, - { - "delta": { - "nodeXY1": { - "x": -294, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 } } - ] - } + } + ] } }, { @@ -10953,26 +10737,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY6": { - "x": 1369, - "y": 9302 - } + "nodes": [ + { + "delta": { + "nodeXY6": { + "x": 1369, + "y": 9302 } - }, - { - "delta": { - "nodeXY1": { - "x": 23, - "y": 505 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 23, + "y": 505 } } - ] - } + } + ] } }, { @@ -11009,26 +10791,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1195, - "y": -1533 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1195, + "y": -1533 } - }, - { - "delta": { - "nodeXY1": { - "x": -29, - "y": -425 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": -29, + "y": -425 } } - ] - } + } + ] } }, { @@ -11065,26 +10845,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -786, - "y": -1510 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -786, + "y": -1510 } - }, - { - "delta": { - "nodeXY1": { - "x": -23, - "y": -448 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": -23, + "y": -448 } } - ] - } + } + ] } }, { @@ -11121,26 +10899,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": 5345, - "y": -1396 - } + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": 5345, + "y": -1396 } - }, - { - "delta": { - "nodeXY1": { - "x": 392, - "y": 17 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 392, + "y": 17 } } - ] - } + } + ] } }, { @@ -11191,48 +10967,46 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2133, - "y": 1785 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2133, + "y": 1785 } }, - { - "delta": { - "nodeXY2": { - "x": 484, - "y": 895 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 484, + "y": 895 } - }, - { - "delta": { - "nodeXY5": { - "x": 29, - "y": 6979 - } - }, - "attributes": { - "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 29, + "y": 6979 } }, - { - "delta": { - "nodeXY5": { - "x": 219, - "y": 5992 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 219, + "y": 5992 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11312,29 +11086,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -4894, - "y": 896 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -4894, + "y": 896 } }, - { - "delta": { - "nodeXY1": { - "x": -294, - "y": 0 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -294, + "y": 0 } } - ] - } + } + ] } }, { @@ -11371,29 +11143,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -4883, - "y": 540 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -4883, + "y": 540 } }, - { - "delta": { - "nodeXY1": { - "x": -323, - "y": -6 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": -6 } } - ] - } + } + ] } } ] @@ -11407,8 +11177,8 @@ } }, { - "description": "Test case 4 - MapTxPojo", - "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2af41559-45b0-48e8-95b4-a2d1368e2bf710002024-11-08T21:52:39.315Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706901702036618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", + "description": "Test case 5 - MapTxPojo", + "input": "mapTxsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload2c91e8d6-f917-4c82-96e4-9de0da3ddca710002024-11-08T22:01:11.319Z70RSUfalse0012834538023000205EA0094D3C71C12CA6CE5D527C02DC3458244800000400028CF6F61F62355F9101464B5AAE70C0A0A631B181A81428D6F27A48302829ADDE94A56050F35BD42952C09C4058340003009609920000010000A2128E4162EAD9980143CC566B6AF028798AF5EB7C050F11349EE19ADCEF4CCA050A35B9E29BE009CE0582C000300960A120000008000222DFE5B6303588D0143CB5AB683C0A0A058F2000080960A920000008000424D3E7162ECF8AF8143CC4C9F8D6028A16876F54814140B1D4000101101632000000014E83CC805050181D34405CC80000000546A74C01414061F5E101832000000015559DAE05050181CA8B06910000008000557F359801414BCCB40000A0A5F6BDEA8050533D307B6C0A1E27EA6FE0AFA9B073027D99945C26C04FB02C360002004B06D1000000800045E50A3E40505331437DAC0A0A6D098BF540143CBEE5BF780A0A67F5501A013ECCC9BA13C027D8161900010025822280000010401AC5437B1027D933B3360141495F5F840A0A62FEF8C581428B624E1CC0A142187100008C3C80008220400203AA400000000F926E6B066F00080F29000000003E45B0481CCC0C583EC800000100012F552960027D9500E77E04FB32AB0218809CE0D89092231E2000118E900011601B200000080002ABF4179027D9958E8EE004E20AE20254561A8000A02B0C40005022C0264000002000115B2C2BC04FB32ACF1F7809C4658F42A6813C4CAEB868F02761B281EA9E004DD364E2D53CC09C4058B40001009600B200000100008AF30177027D9967B06AA04E232A272BEC09E2652CE518813B0D953152C1026E9B2A82A47E04E202C5E0000804401DC8000000051E38FE013EC89FCCA027D84019C8000000052BB904013EC89A097027D84015C80000000538B109813EC0988B31004720000000151DC3EE04FB225C22C09F62C0A840000020000965B0781813D8D599C7FEF02789AB155007204F1356711FFBC09EC058EC0002009604C200000100002B336362809EC6A2FE40170139CD452D7FF502788163D0000802201B2400000002C80D40A027D8067C0020192400000002C825284027D905EC0004FB08085100000000C1AD65AC02788033C00201F4400000003068D912009E2011F0008075100000000C1A1E2F00278804ABF47A7C8195028280540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000RSU10.11.81.20MessageFrame1820121122395806913-10508706921702536618210000000000000000000100000000000-21211567-3670797050-1195249910-1832414920-4313934710-4364951530-42729547-6061000000000006119210000000000000000000100000000000-17521601-2218491230-2662580730-2581556630-32557046-4489982920-44889976-5051000000000006120210000000000000000000010000000000-13131627-2022437830-1194257510300100000000001121210000000000000000000010000000000-8131649-2201444730-3289635840-1930375310290100000000001122301000000000000000000-191163610-12733323301000000000000000000212168810-12135024301000000000000000000684175110-1272982641000000000000000000010000000000020228161024540103503-172107472-293308019-633405115-104747310-101310000000000081274100000000000000000001000000000002370498104419-149108497-344303531-3410810652-104718316-10121000000000008117110000000000000000000001000001000-34231969-1023662010-26299310-2057449120-95121632014001000000000115001000000000216001000000000295010000000000000000003219-4053110305010000000000000000003211-10064096316100000000000000000000010000000002729-1696-107-1089-102736-6046-50393-95130001000000000129001000000000236100000000000000000000100000000001012-1671-102845-6288-60904-18991301000000000051120100000000005226100000000000000000001000000000001430-1698-102767-6178-603194-6835-302990-6513-405135-11024-705003-11021-60221000000000002116100000000000000000001000000000001840-1673-103318-7339-602599-5381-302407-5583-405425-11583-705441-11713-6023100000000000217701000000000000000000-1081-1540-10127-310-106701000000000000000000-649-1528-10104-361-105701000000000000000000-234-1517-1098-3334701000000000000000000238-1545-1092-373-1010810000000000000000000100000000000-2640-253-20-9828-17-30-1007057-30-9788-17-2029100000000000419810000000000000000000100000000000-2452-630-20-1485246-50-15059-11-30301000000000004113901000000000000000000-30661034-10-305012901000000000000000000-3054644-10-3230-10161001000000000000000000-64751452-30-4090151001000000000000000000-65151096-30-3690141001000000000000000000-6521752-30-363-6", "expected": { "metadata": { "logFileName": "", @@ -11419,13 +11189,13 @@ }, "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload", "serialId": { - "streamId": "2af41559-45b0-48e8-95b4-a2d1368e2bf7", + "streamId": "2c91e8d6-f917-4c82-96e4-9de0da3ddca7", "bundleSize": 1, "bundleId": 0, "recordId": 0, "serialNumber": 0 }, - "odeReceivedAt": "2024-11-08T21:52:39.315Z", + "odeReceivedAt": "2024-11-08T22:01:11.319Z", "schemaVersion": 7, "maxDurationTime": 0, "recordGeneratedAt": "", @@ -11451,8 +11221,8 @@ "revision": 2, "refPoint": { "latitude": 39.5806913, - "longitude": "-105.0870690", - "elevation": "1702.0" + "longitude": -105.0870692, + "elevation": 1702.5 }, "laneWidth": 366, "laneSet": { @@ -11505,84 +11275,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2121, - "y": 1567 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": -3670, - "y": 7970 - } - }, - "attributes": { - "dElevation": 50 - } - }, - { - "delta": { - "nodeXY4": { - "x": -1195, - "y": 2499 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -1832, - "y": 4149 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4313, - "y": 9347 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4364, - "y": 9515 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4272, - "y": 9547 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2121, + "y": 1567 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -3670, + "y": 7970 + } + }, + "attributes": { + "dElevation": 50 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1195, + "y": 2499 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -1832, + "y": 4149 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4313, + "y": 9347 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4364, + "y": 9515 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4272, + "y": 9547 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11658,81 +11426,79 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1752, - "y": 1601 - } - } - }, - { - "delta": { - "nodeXY5": { - "x": -2218, - "y": 4912 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2662, - "y": 5807 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2581, - "y": 5566 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": -3255, - "y": 7046 - } - } - }, - { - "delta": { - "nodeXY6": { - "x": -4489, - "y": 9829 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY6": { - "x": -4488, - "y": 9976 - } - }, - "attributes": { - "dElevation": -50 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1752, + "y": 1601 + } + } + }, + { + "delta": { + "nodeXY5": { + "x": -2218, + "y": 4912 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2662, + "y": 5807 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2581, + "y": 5566 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3255, + "y": 7046 + } + } + }, + { + "delta": { + "nodeXY6": { + "x": -4489, + "y": 9829 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -4488, + "y": 9976 + } + }, + "attributes": { + "dElevation": -50 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11808,40 +11574,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1313, - "y": 1627 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1313, + "y": 1627 } - }, - { - "delta": { - "nodeXY5": { - "x": -2022, - "y": 4378 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2022, + "y": 4378 } }, - { - "delta": { - "nodeXY4": { - "x": -1194, - "y": 2575 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1194, + "y": 2575 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -11917,51 +11681,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -813, - "y": 1649 - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -813, + "y": 1649 } - }, - { - "delta": { - "nodeXY5": { - "x": -2201, - "y": 4447 - } - }, - "attributes": { - "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2201, + "y": 4447 } }, - { - "delta": { - "nodeXY5": { - "x": -3289, - "y": 6358 - } - }, - "attributes": { - "dElevation": 40 + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": -3289, + "y": 6358 } }, - { - "delta": { - "nodeXY4": { - "x": -1930, - "y": 3753 - } - }, - "attributes": { - "dElevation": 10 + "attributes": { + "dElevation": 40 + } + }, + { + "delta": { + "nodeXY4": { + "x": -1930, + "y": 3753 } + }, + "attributes": { + "dElevation": 10 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12023,29 +11785,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -191, - "y": 1636 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -191, + "y": 1636 } }, - { - "delta": { - "nodeXY1": { - "x": -127, - "y": 333 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 333 } } - ] - } + } + ] } }, { @@ -12082,29 +11842,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 212, - "y": 1688 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 212, + "y": 1688 } }, - { - "delta": { - "nodeXY1": { - "x": -121, - "y": 350 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -121, + "y": 350 } } - ] - } + } + ] } }, { @@ -12141,29 +11899,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 684, - "y": 1751 - } - }, - "attributes": { - "dElevation": 10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 684, + "y": 1751 } }, - { - "delta": { - "nodeXY1": { - "x": -127, - "y": 298 - } + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -127, + "y": 298 } } - ] - } + } + ] } }, { @@ -12214,84 +11970,82 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 2022, - "y": 816 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 2454, - "y": 0 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY4": { - "x": 3503, - "y": -172 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 7472, - "y": -293 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 8019, - "y": -63 - } - } - }, - { - "delta": { - "nodeXY4": { - "x": 3405, - "y": 115 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4747, - "y": 310 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 2022, + "y": 816 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 2454, + "y": 0 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3503, + "y": -172 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 7472, + "y": -293 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8019, + "y": -63 + } + } + }, + { + "delta": { + "nodeXY4": { + "x": 3405, + "y": 115 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4747, + "y": 310 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12367,76 +12121,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 2370, - "y": 498 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4419, - "y": -149 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY6": { - "x": 8497, - "y": -344 - } - }, - "attributes": { - "dElevation": 30 - } - }, - { - "delta": { - "nodeXY4": { - "x": 3531, - "y": -34 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 8106, - "y": 52 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 4718, - "y": 316 - } - }, - "attributes": { - "dElevation": -10 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 2370, + "y": 498 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4419, + "y": -149 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY6": { + "x": 8497, + "y": -344 + } + }, + "attributes": { + "dElevation": 30 + } + }, + { + "delta": { + "nodeXY4": { + "x": 3531, + "y": -34 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 8106, + "y": 52 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 4718, + "y": 316 + } + }, + "attributes": { + "dElevation": -10 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12512,65 +12264,63 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3423, - "y": 1969 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY2": { - "x": 236, - "y": 620 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY2": { - "x": -262, - "y": 993 - } - }, - "attributes": { - "dElevation": 10 - } - }, - { - "delta": { - "nodeXY5": { - "x": -2057, - "y": 4491 - } - }, - "attributes": { - "dElevation": 20 - } - }, - { - "delta": { - "nodeXY4": { - "x": -951, - "y": 2163 - } - }, - "attributes": { - "dElevation": 20 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3423, + "y": 1969 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY2": { + "x": 236, + "y": 620 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY2": { + "x": -262, + "y": 993 + } + }, + "attributes": { + "dElevation": 10 + } + }, + { + "delta": { + "nodeXY5": { + "x": -2057, + "y": 4491 + } + }, + "attributes": { + "dElevation": 20 + } + }, + { + "delta": { + "nodeXY4": { + "x": -951, + "y": 2163 + } + }, + "attributes": { + "dElevation": 20 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12670,26 +12420,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 3219, - "y": -405 - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 3219, + "y": -405 } - }, - { - "delta": { - "nodeXY1": { - "x": 311, - "y": 0 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 311, + "y": 0 } } - ] - } + } + ] } }, { @@ -12726,26 +12474,24 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 3211, - "y": -1006 - } + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 3211, + "y": -1006 } - }, - { - "delta": { - "nodeXY1": { - "x": 409, - "y": 6 - } + } + }, + { + "delta": { + "nodeXY1": { + "x": 409, + "y": 6 } } - ] - } + } + ] } }, { @@ -12796,51 +12542,49 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": 2729, - "y": -1696 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": 2729, + "y": -1696 } }, - { - "delta": { - "nodeXY3": { - "x": 7, - "y": -1089 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY3": { + "x": 7, + "y": -1089 } }, - { - "delta": { - "nodeXY5": { - "x": 2736, - "y": -6046 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2736, + "y": -6046 } }, - { - "delta": { - "nodeXY2": { - "x": 393, - "y": -951 - } + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY2": { + "x": 393, + "y": -951 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -12935,40 +12679,38 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1012, - "y": -1671 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1012, + "y": -1671 } }, - { - "delta": { - "nodeXY5": { - "x": 2845, - "y": -6288 - } - }, - "attributes": { - "dElevation": -60 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2845, + "y": -6288 } }, - { - "delta": { - "nodeXY3": { - "x": 904, - "y": -1899 - } + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY3": { + "x": 904, + "y": -1899 } } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13065,76 +12807,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1430, - "y": -1698 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2767, - "y": -6178 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY5": { - "x": 3194, - "y": -6835 - } - }, - "attributes": { - "dElevation": -30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2990, - "y": -6513 - } - }, - "attributes": { - "dElevation": -40 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5135, - "y": -11024 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5003, - "y": -11021 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1430, + "y": -1698 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2767, + "y": -6178 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3194, + "y": -6835 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2990, + "y": -6513 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5135, + "y": -11024 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5003, + "y": -11021 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13210,76 +12950,74 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 1840, - "y": -1673 - } - }, - "attributes": { - "dElevation": -10 - } - }, - { - "delta": { - "nodeXY5": { - "x": 3318, - "y": -7339 - } - }, - "attributes": { - "dElevation": -60 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2599, - "y": -5381 - } - }, - "attributes": { - "dElevation": -30 - } - }, - { - "delta": { - "nodeXY5": { - "x": 2407, - "y": -5583 - } - }, - "attributes": { - "dElevation": -40 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5425, - "y": -11583 - } - }, - "attributes": { - "dElevation": -70 - } - }, - { - "delta": { - "nodeXY6": { - "x": 5441, - "y": -11713 - } - }, - "attributes": { - "dElevation": -60 - } - } - ] - } + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 1840, + "y": -1673 + } + }, + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY5": { + "x": 3318, + "y": -7339 + } + }, + "attributes": { + "dElevation": -60 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2599, + "y": -5381 + } + }, + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY5": { + "x": 2407, + "y": -5583 + } + }, + "attributes": { + "dElevation": -40 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5425, + "y": -11583 + } + }, + "attributes": { + "dElevation": -70 + } + }, + { + "delta": { + "nodeXY6": { + "x": 5441, + "y": -11713 + } + }, + "attributes": { + "dElevation": -60 + } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13341,32 +13079,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -1081, - "y": -1540 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -1081, + "y": -1540 } }, - { - "delta": { - "nodeXY1": { - "x": 127, - "y": -310 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 127, + "y": -310 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13403,32 +13139,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -649, - "y": -1528 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -649, + "y": -1528 } }, - { - "delta": { - "nodeXY1": { - "x": 104, - "y": -361 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 104, + "y": -361 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13465,29 +13199,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": -234, - "y": -1517 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": -234, + "y": -1517 } }, - { - "delta": { - "nodeXY1": { - "x": 98, - "y": -333 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 98, + "y": -333 } } - ] - } + } + ] } }, { @@ -13524,32 +13256,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY3": { - "x": 238, - "y": -1545 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY3": { + "x": 238, + "y": -1545 } }, - { - "delta": { - "nodeXY1": { - "x": 92, - "y": -373 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": 92, + "y": -373 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13600,54 +13330,52 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2640, - "y": -253 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2640, + "y": -253 } }, - { - "delta": { - "nodeXY6": { - "x": -9828, - "y": -17 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9828, + "y": -17 } }, - { - "delta": { - "nodeXY6": { - "x": -10070, - "y": 57 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -10070, + "y": 57 } }, - { - "delta": { - "nodeXY6": { - "x": -9788, - "y": -17 - } - }, - "attributes": { - "dElevation": -20 + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY6": { + "x": -9788, + "y": -17 } + }, + "attributes": { + "dElevation": -20 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13723,43 +13451,41 @@ "caution": false }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -2452, - "y": -630 - } - }, - "attributes": { - "dElevation": -20 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -2452, + "y": -630 } }, - { - "delta": { - "nodeXY6": { - "x": -14852, - "y": 46 - } - }, - "attributes": { - "dElevation": -50 + "attributes": { + "dElevation": -20 + } + }, + { + "delta": { + "nodeXY6": { + "x": -14852, + "y": 46 } }, - { - "delta": { - "nodeXY6": { - "x": -15059, - "y": -11 - } - }, - "attributes": { - "dElevation": -30 + "attributes": { + "dElevation": -50 + } + }, + { + "delta": { + "nodeXY6": { + "x": -15059, + "y": -11 } + }, + "attributes": { + "dElevation": -30 } - ] - } + } + ] }, "connectsTo": { "connectsTo": [ @@ -13821,29 +13547,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3066, - "y": 1034 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3066, + "y": 1034 } }, - { - "delta": { - "nodeXY1": { - "x": -305, - "y": 0 - } + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -305, + "y": 0 } } - ] - } + } + ] } }, { @@ -13880,32 +13604,30 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY4": { - "x": -3054, - "y": 644 - } - }, - "attributes": { - "dElevation": -10 + "nodes": [ + { + "delta": { + "nodeXY4": { + "x": -3054, + "y": 644 } }, - { - "delta": { - "nodeXY1": { - "x": -323, - "y": 0 - } - }, - "attributes": { - "dElevation": -10 + "attributes": { + "dElevation": -10 + } + }, + { + "delta": { + "nodeXY1": { + "x": -323, + "y": 0 } + }, + "attributes": { + "dElevation": -10 } - ] - } + } + ] } }, { @@ -13942,29 +13664,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6475, - "y": 1452 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6475, + "y": 1452 } }, - { - "delta": { - "nodeXY1": { - "x": -409, - "y": 0 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -409, + "y": 0 } } - ] - } + } + ] } }, { @@ -14001,29 +13721,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6515, - "y": 1096 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6515, + "y": 1096 } }, - { - "delta": { - "nodeXY1": { - "x": -369, - "y": 0 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -369, + "y": 0 } } - ] - } + } + ] } }, { @@ -14060,29 +13778,27 @@ } }, "nodeList": { - "nodes": { - "NodeXY": [ - { - "delta": { - "nodeXY5": { - "x": -6521, - "y": 752 - } - }, - "attributes": { - "dElevation": -30 + "nodes": [ + { + "delta": { + "nodeXY5": { + "x": -6521, + "y": 752 } }, - { - "delta": { - "nodeXY1": { - "x": -363, - "y": -6 - } + "attributes": { + "dElevation": -30 + } + }, + { + "delta": { + "nodeXY1": { + "x": -363, + "y": -6 } } - ] - } + } + ] } } ] From d93e6ec05e77920990eef1704ca99efc7c6a2593 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 25 Nov 2024 02:31:22 -0700 Subject: [PATCH 066/264] Update schemas --- .../main/resources/schemas/schema-map.json | 590 +++++++++--------- .../main/resources/schemas/schema-tim.json | 500 +++------------ 2 files changed, 380 insertions(+), 710 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-map.json b/jpo-ode-core/src/main/resources/schemas/schema-map.json index 85495546a..89c102e49 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-map.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-map.json @@ -1,4 +1,4 @@ -{ +{ "$schema": "http://json-schema.org/draft-04/schema#", "properties": { "metadata": { @@ -791,185 +791,177 @@ "nodeList": { "properties": { "nodes": { - "properties": { - "NodeXY": { - "items": [ - { + "type": "array", + "items": [ + { + "properties": { + "attributes": { + "properties": { + "dElevation": { + "type": "number" + }, + "dWidth": { + "type": "null" + }, + "data": { + "type": "null" + }, + "disabled": { + "type": "null" + }, + "enabled": { + "type": "null" + }, + "localNode": { + "type": "null" + } + }, + "required": [ + "dElevation" + ], + "type": [ + "object", + "null" + ] + }, + "delta": { "properties": { - "attributes": { + "nodeLatLon": { "properties": { - "dElevation": { + "lat": { "type": "number" }, - "dWidth": { - "type": "null" - }, - "data": { - "type": "null" - }, - "disabled": { - "type": "null" - }, - "enabled": { - "type": "null" - }, - "localNode": { - "type": "null" + "lon": { + "type": "number" } }, "required": [ - "dElevation" + "lon", + "lat" ], "type": [ "object", "null" ] }, - "delta": { + "nodeXY1": { "properties": { - "nodeLatLon": { - "properties": { - "lat": { - "type": "number" - }, - "lon": { - "type": "number" - } - }, - "required": [ - "lon", - "lat" - ], - "type": [ - "object", - "null" - ] + "x": { + "type": "number" }, - "nodeXY1": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY2": { + "properties": { + "x": { + "type": "number" }, - "nodeXY2": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY3": { + "properties": { + "x": { + "type": "number" }, - "nodeXY3": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY4": { + "properties": { + "x": { + "type": "number" }, - "nodeXY4": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY5": { + "properties": { + "x": { + "type": "number" }, - "nodeXY5": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY6": { + "properties": { + "x": { + "type": "number" }, - "nodeXY6": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" } }, - "type": "object" + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] } }, - "required": [ - "delta" - ], "type": "object" } + }, + "required": [ + "delta" ], - "type": "array" + "type": "object" } - }, - "required": [ - "NodeXY" - ], - "type": "object" + ] } }, "required": [ @@ -1821,185 +1813,177 @@ "nodeList": { "properties": { "nodes": { - "properties": { - "NodeXY": { - "items": [ - { + "type": "array", + "items": [ + { + "properties": { + "attributes": { + "properties": { + "dElevation": { + "type": "number" + }, + "dWidth": { + "type": "null" + }, + "data": { + "type": "null" + }, + "disabled": { + "type": "null" + }, + "enabled": { + "type": "null" + }, + "localNode": { + "type": "null" + } + }, + "required": [ + "dElevation" + ], + "type": [ + "object", + "null" + ] + }, + "delta": { "properties": { - "attributes": { + "nodeLatLon": { "properties": { - "dElevation": { + "lat": { "type": "number" }, - "dWidth": { - "type": "null" - }, - "data": { - "type": "null" - }, - "disabled": { - "type": "null" - }, - "enabled": { - "type": "null" - }, - "localNode": { - "type": "null" + "lon": { + "type": "number" } }, "required": [ - "dElevation" + "lon", + "lat" ], "type": [ "object", "null" ] }, - "delta": { + "nodeXY1": { "properties": { - "nodeLatLon": { - "properties": { - "lat": { - "type": "number" - }, - "lon": { - "type": "number" - } - }, - "required": [ - "lon", - "lat" - ], - "type": [ - "object", - "null" - ] + "x": { + "type": "number" }, - "nodeXY1": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY2": { + "properties": { + "x": { + "type": "number" }, - "nodeXY2": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY3": { + "properties": { + "x": { + "type": "number" }, - "nodeXY3": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY4": { + "properties": { + "x": { + "type": "number" }, - "nodeXY4": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY5": { + "properties": { + "x": { + "type": "number" }, - "nodeXY5": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] + }, + "nodeXY6": { + "properties": { + "x": { + "type": "number" }, - "nodeXY6": { - "properties": { - "x": { - "type": "number" - }, - "y": { - "type": "number" - } - }, - "required": [ - "x", - "y" - ], - "type": [ - "object", - "null" - ] + "y": { + "type": "number" } }, - "type": "object" + "required": [ + "x", + "y" + ], + "type": [ + "object", + "null" + ] } }, - "required": [ - "delta" - ], "type": "object" } + }, + "required": [ + "delta" ], - "type": "array" + "type": "object" } - }, - "required": [ - "NodeXY" - ], - "type": "object" + ] } }, "required": [ diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index 14ccfb46e..d539c00e9 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -22,7 +22,7 @@ "type": "string" }, "maxDurationTime": { - "type": "string" + "type": "number" }, "odePacketID": { "type": "string" @@ -40,7 +40,12 @@ "type": "string" }, "receivedMessageDetails": { - "type": "string" + "type": "object", + "properties": { + "rxSource": { + "type": "string" + } + } }, "recordGeneratedAt": { "type": "string" @@ -52,10 +57,10 @@ "type": "string" }, "sanitized": { - "type": "string" + "type": "boolean" }, "schemaVersion": { - "type": "string" + "type": "number" }, "securityResultCode": { "type": "string" @@ -285,16 +290,16 @@ "type": "object", "properties": { "bundleId": { - "type": "string" + "type": "number" }, "bundleSize": { - "type": "string" + "type": "number" }, "recordId": { - "type": "string" + "type": "number" }, "serialNumber": { - "type": "string" + "type": "number" }, "streamId": { "type": "string" @@ -312,15 +317,7 @@ "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "MessageFrame": { - "$ref": "#/$defs/OdeTimMessageFrame" - } - }, - "required": [ - "MessageFrame" - ] + "$ref": "#/$defs/J2735Tim" }, "dataType": { "type": "string" @@ -331,29 +328,6 @@ "dataType" ] }, - "OdeTimMessageFrame": { - "type": "object", - "properties": { - "messageId": { - "type": "string" - }, - "value": { - "type": "object", - "properties": { - "TravelerInformation": { - "$ref": "#/$defs/J2735Tim" - } - }, - "required": [ - "TravelerInformation" - ] - } - }, - "required": [ - "messageId", - "value" - ] - }, "J2735Tim": { "type": "object", "properties": { @@ -367,17 +341,10 @@ "type": "string" }, "dataFrames": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/OdeTimDataFrame" - } - ] - }, + "type": "array", + "prefixItems": [ { - "$ref": "#/$defs/OdeTimDataFrame" + "$ref": "#/$defs/J2735TravelerDataFrame" } ] }, @@ -390,29 +357,6 @@ "msgCnt" ] }, - "OdeTimDataFrame": { - "type": "object", - "properties": { - "TravelerDataFrame": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735TravelerDataFrame" - } - ] - }, - { - "$ref": "#/$defs/J2735TravelerDataFrame" - } - ] - } - }, - "required": [ - "TravelerDataFrame" - ] - }, "J2735TravelerDataFrame": { "type": "object", "properties": { @@ -420,7 +364,12 @@ "type": "string" }, "frameType": { - "$ref": "#/$defs/J2735DF_FrameType" + "enum": [ + "unknown", + "advisory", + "roadSignage", + "commercialSignage" + ] }, "msgId": { "oneOf": [ @@ -456,17 +405,10 @@ "type": "string" }, "regions": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735DF_Regions" - } - ] - }, + "type": "array", + "prefixItems": [ { - "$ref": "#/$defs/J2735DF_Regions" + "$ref": "#/$defs/J2735DF_GeographicalPath" } ] }, @@ -497,54 +439,6 @@ "content" ] }, - "J2735DF_FrameType": { - "oneOf": [ - { - "type": "object", - "properties": { - "unknown": { - "type": "string" - } - }, - "required": [ - "unknown" - ] - }, - { - "type": "object", - "properties": { - "advisory": { - "type": "string" - } - }, - "required": [ - "advisory" - ] - }, - { - "type": "object", - "properties": { - "roadSignage": { - "type": "string" - } - }, - "required": [ - "roadSignage" - ] - }, - { - "type": "object", - "properties": { - "commercialSignage": { - "type": "string" - } - }, - "required": [ - "commercialSignage" - ] - } - ] - }, "J2735DF_MsgId_RoadSignId": { "type": "object", "properties": { @@ -552,13 +446,21 @@ "type": "object", "properties": { "position": { - "$ref": "#/$defs/J2735Position3D" + "$ref": "#/$defs/OdePosition3D" }, "viewAngle": { "type": "string" }, "mutcdCode": { - "$ref": "#/$defs/J2735MUTCDCode" + "enum": [ + "none", + "regulatory", + "warning", + "maintenance", + "motoristService", + "guide", + "rec" + ] } }, "required": [ @@ -571,29 +473,6 @@ "roadSignID" ] }, - "J2735DF_Regions": { - "type": "object", - "properties": { - "GeographicalPath": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735DF_GeographicalPath" - } - ] - }, - { - "$ref": "#/$defs/J2735DF_GeographicalPath" - } - ] - } - }, - "required": [ - "GeographicalPath" - ] - }, "J2735DF_GeographicalPath": { "type": "object", "properties": { @@ -604,16 +483,21 @@ "$ref": "#/$defs/J2735RoadSegmentReferenceID" }, "anchor": { - "$ref": "#/$defs/J2735Position3D" + "$ref": "#/$defs/OdePosition3D" }, "laneWidth": { - "type": "string" + "type": "number" }, "directionality": { - "$ref": "#/$defs/J2735DirectionOfUse" + "enum": [ + "unavailable", + "forward", + "reverse", + "both" + ] }, "closedPath": { - "$ref": "#/$defs/BooleanObject" + "type": "boolean" }, "direction": { "type": "string" @@ -626,73 +510,13 @@ "description" ] }, - "J2735DirectionOfUse": { - "oneOf": [ - { - "type": "object", - "properties": { - "unavailable": { - "type": "string" - } - }, - "required": [ - "unavailable" - ] - }, - { - "type": "object", - "properties": { - "forward": { - "type": "string" - } - }, - "required": [ - "forward" - ] - }, - { - "type": "object", - "properties": { - "reverse": { - "type": "string" - } - }, - "required": [ - "reverse" - ] - }, - { - "type": "object", - "properties": { - "both": { - "type": "string" - } - }, - "required": [ - "both" - ] - } - ] - }, "J2735DF_Regions_Description": { "oneOf": [ { "type": "object", "properties": { "path": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735OffsetSystem" - } - ] - }, - { - "$ref": "#/$defs/J2735OffsetSystem" - } - ] + "$ref": "#/$defs/J2735OffsetSystem" } }, "required": [ @@ -703,19 +527,7 @@ "type": "object", "properties": { "geometry": { - "oneOf": [ - { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735GeometricProjection" - } - ] - }, - { - "$ref": "#/$defs/J2735GeometricProjection" - } - ] + "$ref": "#/$defs/J2735GeometricProjection" } }, "required": [ @@ -728,7 +540,7 @@ "type": "object", "properties": { "scale": { - "type": "string" + "type": "number" }, "offset": { "oneOf": [ @@ -765,19 +577,11 @@ "type": "object", "properties": { "nodes": { - "type": "object", - "properties": { - "NodeXY": { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735NodeXY" - } - ] + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/J2735NodeXY" } - }, - "required": [ - "NodeXY" ] } }, @@ -789,19 +593,11 @@ "type": "object", "properties": { "nodes": { - "type": "object", - "properties": { - "NodeLL": { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735NodeLL" - } - ] + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/J2735NodeLL" } - }, - "required": [ - "NodeLL" ] } }, @@ -817,78 +613,78 @@ { "type": "object", "properties": { - "node-XY1": { + "nodeXY1": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY1" + "nodeXY1" ] }, { "type": "object", "properties": { - "node-XY2": { + "nodeXY2": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY2" + "nodeXY2" ] }, { "type": "object", "properties": { - "node-XY3": { + "nodeXY3": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY3" + "nodeXY3" ] }, { "type": "object", "properties": { - "node-XY4": { + "nodeXY4": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY4" + "nodeXY4" ] }, { "type": "object", "properties": { - "node-XY5": { + "nodeXY5": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY5" + "nodeXY5" ] }, { "type": "object", "properties": { - "node-XY6": { + "nodeXY6": { "$ref": "#/$defs/J2735NodeXYDelta" } }, "required": [ - "node-XY6" + "nodeXY6" ] }, { "type": "object", "properties": { - "node-LatLon": { + "nodeLatLon": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LatLon" + "nodeLatLon" ] } ] @@ -906,78 +702,78 @@ { "type": "object", "properties": { - "node-LL1": { + "nodeLL1": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL1" + "nodeLL1" ] }, { "type": "object", "properties": { - "node-LL2": { + "nodeLL2": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL2" + "nodeLL2" ] }, { "type": "object", "properties": { - "node-LL3": { + "nodeLL3": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL3" + "nodeLL3" ] }, { "type": "object", "properties": { - "node-LL4": { + "nodeLL4": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL4" + "nodeLL4" ] }, { "type": "object", "properties": { - "node-LL5": { + "nodeLL5": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL5" + "nodeLL5" ] }, { "type": "object", "properties": { - "node-LL6": { + "nodeLL6": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LL6" + "nodeLL6" ] }, { "type": "object", "properties": { - "node-LatLon": { + "nodeLatLon": { "$ref": "#/$defs/J2735NodeLLDelta" } }, "required": [ - "node-LatLon" + "nodeLatLon" ] } ] @@ -991,10 +787,10 @@ "type": "object", "properties": { "x": { - "type": "string" + "type": "number" }, "y": { - "type": "string" + "type": "number" } }, "required": [ @@ -1006,10 +802,10 @@ "type": "object", "properties": { "lat": { - "type": "string" + "type": "number" }, "lon": { - "type": "string" + "type": "number" } }, "required": [ @@ -1188,16 +984,13 @@ "type": "object", "properties": { "latitude": { - "type": "string" + "type": "number" }, "longitude": { - "type": "string" + "type": "number" }, "elevation": { - "type": [ - "string", - "null" - ] + "type": "number" } }, "required": [ @@ -1205,95 +998,14 @@ "longitude" ] }, - "J2735MUTCDCode": { - "oneOf": [ - { - "type": "object", - "properties": { - "none": { - "type": "string" - } - }, - "required": [ - "none" - ] - }, - { - "type": "object", - "properties": { - "regulatory": { - "type": "string" - } - }, - "required": [ - "regulatory" - ] - }, - { - "type": "object", - "properties": { - "warning": { - "type": "string" - } - }, - "required": [ - "warning" - ] - }, - { - "type": "object", - "properties": { - "maintenance": { - "type": "string" - } - }, - "required": [ - "maintenance" - ] - }, - { - "type": "object", - "properties": { - "motoristService": { - "type": "string" - } - }, - "required": [ - "motoristService" - ] - }, - { - "type": "object", - "properties": { - "guide": { - "type": "string" - } - }, - "required": [ - "guide" - ] - }, - { - "type": "object", - "properties": { - "rec": { - "type": "string" - } - }, - "required": [ - "rec" - ] - } - ] - }, "J2735RoadSegmentReferenceID": { "type": "object", "properties": { "id": { - "type": "string" + "type": "number" }, "region": { - "type": "string" + "type": "number" } }, "required": [ @@ -1391,32 +1103,6 @@ ] } ] - }, - "BooleanObject": { - "oneOf": [ - { - "type": "object", - "properties": { - "true": { - "type": "string" - } - }, - "required": [ - "true" - ] - }, - { - "type": "object", - "properties": { - "false": { - "type": "string" - } - }, - "required": [ - "false" - ] - } - ] } } } \ No newline at end of file From 6848ede5f788bcb23884d63a43ee03b5f6aa6bff Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 25 Nov 2024 14:13:09 -0700 Subject: [PATCH 067/264] Add support for unsigned TIMs to go to the TMC filtered topic --- .../dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java | 4 ++++ .../us/dot/its/jpo/ode/traveler/TimDepositController.java | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index e12831bfe..59a0bd15c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -273,6 +273,7 @@ public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consumedObj) { // Send TIMs and record results HashMap responseList = new HashMap<>(); + JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); JSONObject dataObj = consumedObj .getJSONObject(AppContext.PAYLOAD_STRING) @@ -312,6 +313,9 @@ public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consum JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); String encodedTim = mfObj.getString(BYTES); + // Deposit encoded TIM to TMC-filtered topic if TMC-generated + depositToFilteredTopic(metadataObj, encodedTim); + // if header is present, strip it if (isHeaderPresent(encodedTim)) { String header = encodedTim.substring(0, encodedTim.indexOf("001F") + 4); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 8291b1fee..daa5b8372 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -256,7 +256,6 @@ public synchronized ResponseEntity depositTim(String jsonString, Request if (xmlMsg != null) { log.debug("XML representation: {}", xmlMsg); - stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); // Convert XML into ODE TIM JSON object and obfuscate RSU password OdeTimData odeTimObj = OdeTimDataCreatorHelper.createOdeTimDataFromCreator(xmlMsg, timMetadata); @@ -268,6 +267,10 @@ public synchronized ResponseEntity depositTim(String jsonString, Request // publish J2735 TIM also to general un-filtered TIM topic with streamID as key stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); + + // Write XML to the encoder input topic at the end to ensure the correct order of operations to pair + // each message to an OdeTimJson streamId key + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); } serialIdOde.increment(); From 8b8de0c751dea77cef0467d4776dea7aef475d7c Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Tue, 26 Nov 2024 01:05:25 -0700 Subject: [PATCH 068/264] Update unit tests to address recent changes --- .../test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java index 9a626ccff..5a1b0debb 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java @@ -16,9 +16,9 @@ public class OdeTimDataTest { private static final String SCHEMA_VERSION = "7"; - private static final String ASN1_STRING = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e"; + private static final String ASN1_STRING = "001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100"; - private static final String json = String.format("{\"metadata\":{\"securityResultCode\":\"\",\"recordGeneratedBy\":\"RSU\",\"schemaVersion\":\"%s\",\"odePacketID\":\"\",\"sanitized\":\"false\",\"asn1\":\"%s\",\"recordType\":\"timMsg\",\"recordGeneratedAt\":\"\",\"maxDurationTime\":\"0\",\"odeTimStartDateTime\":\"\",\"receivedMessageDetails\":\"\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"recordId\":\"0\",\"serialNumber\":\"0\",\"streamId\":\"11ad5323-ec81-4694-8cd0-eb88ca08728e\",\"bundleSize\":\"1\",\"bundleId\":\"0\"},\"logFileName\":\"\",\"odeReceivedAt\":\"2022-12-24T02:24:38.248417Z\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"data\":{\"MessageFrame\":{\"messageId\":\"31\",\"value\":{\"TravelerInformation\":{\"timeStamp\":\"449089\",\"packetID\":\"0000000000000BBC2B\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":{\"regions\":{\"GeographicalPath\":{\"closedPath\":{\"false\":\"\"},\"anchor\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"},\"name\":\"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456\",\"laneWidth\":\"32700\",\"directionality\":{\"both\":\"\"},\"description\":{\"path\":{\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047287423\",\"lat\":\"411264686\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047305390\",\"lat\":\"411260104\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047323629\",\"lat\":\"411256185\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047342080\",\"lat\":\"411252886\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047360706\",\"lat\":\"411250207\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047379480\",\"lat\":\"411248201\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047398354\",\"lat\":\"411246839\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047417290\",\"lat\":\"411246133\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047436246\",\"lat\":\"411245796\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047455202\",\"lat\":\"411245470\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047474159\",\"lat\":\"411245173\"}}}]}}},\"scale\":\"0\"}},\"id\":{\"id\":\"0\",\"region\":\"0\"},\"direction\":\"0000000000010000\"}},\"durationTime\":\"1440\",\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"startYear\":\"2018\",\"msgId\":{\"roadSignID\":{\"viewAngle\":\"1111111111111111\",\"mutcdCode\":{\"warning\":\"\"},\"position\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"}}},\"priority\":\"5\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"777\"}},{\"item\":{\"itis\":\"13579\"}}]}},\"url\":\"null\",\"notUsed\":\"0\",\"notUsed1\":\"0\",\"frameType\":{\"advisory\":\"\"},\"startTime\":\"448260\"}},\"msgCnt\":\"1\"}}}},\"dataType\":\"TravelerInformation\"}}", SCHEMA_VERSION, ASN1_STRING); + private static final String json = String.format("{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"89b9de68-7e91-4491-886f-d95276b67907\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-11-26T07:29:12.257Z\",\"schemaVersion\":7,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Tim\",\"data\":{\"msgCnt\":\"1\",\"timeStamp\":\"417415\",\"packetID\":\"AD5DB73EE53601D49C\",\"dataFrames\":[{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"428312\",\"durationTime\":\"30\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"I_US-24_RSU_10.16.28.6\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1726,\"lat\":111}}},{\"delta\":{\"nodeLL5\":{\"lon\":1208360,\"lat\":77510}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"1025\"}}]}}},{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"428312\",\"durationTime\":\"30\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"I_US-24_RSU_10.16.28.6\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1726,\"lat\":111}}},{\"delta\":{\"nodeLL5\":{\"lon\":1208360,\"lat\":77510}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"770\"}}]}}}]}}}", SCHEMA_VERSION, ASN1_STRING); // // Note that OdeTimData does not have annotations to support deserialization, so serialization/deserialization is not tested here. From 1973dc73bdad28280af19f6fb541e4d044906063 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 26 Nov 2024 12:20:48 -0700 Subject: [PATCH 069/264] Updated models to ensure compliance with J2735 2024 --- .../j2735/OdeTravelerInformationMessage.java | 40 ++++++++--------- .../j2735/timstorage/TravelerDataFrame.java | 44 +++++++++---------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index 4e38a6617..042037fbc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -450,16 +450,16 @@ public void setdElevation(BigDecimal dElevation) { public static class DataFrame extends OdeObject { private static final long serialVersionUID = 537503046055742396L; - private short notUsed;// Start Header Information + private short doNotUse1;// Start Header Information private FrameType.TravelerInfoType frameType; private MsgId msgId; private String startDateTime; private int durationTime; private int priority;// End header Information - private short notUsed1;// Start Region Information + private short doNotUse2;// Start Region Information private Region[] regions; - private short notUsed2;// Start content Information - private short notUsed3; + private short doNotUse3;// Start content Information + private short doNotUse4; private String content; private String[] items; private String url;// End content Information @@ -990,36 +990,36 @@ public void setFrameType(FrameType.TravelerInfoType frameType) { this.frameType = frameType; } - public short getNotUsed() { - return notUsed; + public short getDoNotUse1() { + return doNotUse1; } - public void setNotUsed(short sspTimRights) { - this.notUsed = sspTimRights; + public void setDoNotUse1(short doNotUse1) { + this.doNotUse1 = doNotUse1; } - public short getNotUsed1() { - return notUsed1; + public short getDoNotUse2() { + return doNotUse2; } - public void setNotUsed1(short sspLocationRights) { - this.notUsed1 = sspLocationRights; + public void setDoNotUse2(short doNotUse2) { + this.doNotUse2 = doNotUse2; } - public short getNotUsed2() { - return notUsed2; + public short getDoNotUse3() { + return doNotUse3; } - public void setNotUsed2(short sspMsgTypes) { - this.notUsed2 = sspMsgTypes; + public void setDoNotUse3(short doNotUse3) { + this.doNotUse3 = doNotUse3; } - public short getNotUsed3() { - return notUsed3; + public short getDoNotUse4() { + return doNotUse4; } - public void setNotUsed3(short sspMsgContent) { - this.notUsed3 = sspMsgContent; + public void setDoNotUse4(short doNotUse4) { + this.doNotUse4 = doNotUse4; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java index 381c89ce1..452f5171f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java @@ -21,12 +21,12 @@ import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "notUsed", "frameType", "msgId", "startYear", "startTime", "durationTime", "priority", - "notUsed1", "regions", "notUsed2", "notUsed3", "tcontent", "url" }) +@JsonPropertyOrder({ "doNotUse1", "frameType", "msgId", "startYear", "startTime", "durationTime", "priority", + "doNotUse2", "regions", "doNotUse3", "doNotUse4", "tcontent", "url" }) public class TravelerDataFrame extends Asn1Object { private static final long serialVersionUID = 1L; - private String notUsed; + private String doNotUse1; private FrameType frameType; @@ -40,25 +40,25 @@ public class TravelerDataFrame extends Asn1Object { private String priority; - private String notUsed1; + private String doNotUse2; private Regions regions; - private String notUsed2; + private String doNotUse3; - private String notUsed3; + private String doNotUse4; @JsonProperty("tcontent") private Content tcontent; private String url; - public String getNotUsed1() { - return notUsed1; + public String getDoNotUse2() { + return doNotUse2; } - public void setNotUsed1(String sspLocationRights) { - this.notUsed1 = sspLocationRights; + public void setDoNotUse2(String doNotUse2) { + this.doNotUse2 = doNotUse2; } @@ -143,27 +143,27 @@ public void setMsgId(MsgId msgId) { this.msgId = msgId; } - public String getNotUsed3() { - return notUsed3; + public String getDoNotUse4() { + return doNotUse4; } - public void setNotUsed3(String sspMsgRights2) { - this.notUsed3 = sspMsgRights2; + public void setDoNotUse4(String doNotUse4) { + this.doNotUse4 = doNotUse4; } - public String getNotUsed() { - return notUsed; + public String getDoNotUse1() { + return doNotUse1; } - public void setNotUsed(String sspTimRights) { - this.notUsed = sspTimRights; + public void setDoNotUse1(String doNotUse1) { + this.doNotUse1 = doNotUse1; } - public String getNotUsed2() { - return notUsed2; + public String getDoNotUse3() { + return doNotUse3; } - public void setNotUsed2(String sspMsgRights1) { - this.notUsed2 = sspMsgRights1; + public void setDoNotUse3(String doNotUse3) { + this.doNotUse3 = doNotUse3; } } From 6f700e28a3eb0e7ad32a21c5e26817f52affe5fd Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Tue, 26 Nov 2024 12:36:07 -0700 Subject: [PATCH 070/264] Spring Kafka Proof-of-Concept - Implemented in MAP Data Flow (#118) * unify tests in Asn1DecodedDataRouterApprovalTest and prepend TEST to topic names in Asn1DecodeMAPJSONTest for unique topic naming to avoid topic name conflicts across tests * add spring.application.name to application.yaml to support Spring Boot kafka consumer and producer automatic naming * Add Asn1DecodeMAPJSONListener and KafkaConsumerConfig to use Spring Kafka listener for Asn1DecodeMAPJSONTest. Test is not passing, but is proving that the new listener consumes the message as expected * comment out outputSchemaVersion in OdeProperties and add Import annotation for BuildProperties.class to allow usage of SpringBootTest annotations. BuildProperties wasn't found unless mvn package was run prior to testing. That's slow and not intuitive, so the annotation fixed the issue. Commenting out outputSchemaVersion allowed for setting OdeProperties as a Component instead of a Configuration class, since that's essentially what it is, and we don't need output schema to be served from a bean in the long run. It can be used as a Value annotated field wherever needed instead * Use EmbeddedKafkaHolder for single EmbeddedKafka instance across test cases and migrate Asn1DecodeMAPJSONTest to use it * Implement KafkaProducerConfig and XMLOdeObjectSerializer to support producing OdeObjects. Not correct for use case, but does prove we can use KafkaTemplates alongside hand-rolled producers * Set kafka broker address to localhost:9093 in test application.yaml to ensure EmbeddedKafka broker doesn't fail to start up when a kafka broker is already running in a dev container on 9092 * Set kafka broker address to localhost:4242 in test application.yaml to ensure EmbeddedKafka broker doesn't fail to start up when a kafka broker is already running in a dev container on 9092 and 9093 * set kafka.consumer and kafka.producer properties in application.yaml to defaults from MessageConsumer and MessageProducer to enable correct startup connections. This proves we can simultaneously run Spring Kafka with our hand-rolled kafka implementations! * increase TimIngestTrackerProperies default interval from 1 to 10 seconds for test runs to reduce log noise * remove Asn1DecodedDataRouter from Asn1DecodedDataRouterApprovalTest since SpringBootTest loads the beans into the context automatically now * use asn1 encoded hex strings as inputs for MapReceiverTest instead of plain json objects * replace hand-rolled producer in MapReceiver with KafkaTemplate * simplify test setup by using SpringBootTest annotation and the EmbeddedKafkaBrokerHolder in MapReceiverTest * use the correct test group name when creating test consumer in MapReceiverTest * comment out MAP routing in Asn1DecodedDataRouter to prove Asn1DecodedDataRouterApprovalTest fails before implementation of spring kafka consumer-producer * Move all Topics configuration objects into subpackage named topics * Move Asn1DecodeMAPJSONListener to kafka.listeners package * Add UnsupportedDataTypeException to prevent acknowledgment of MAP consumption by Asn1DecodedDataRouter * Add filtering consumer factory to support processing of MAP messages in Asn1DecodedDataListener (also implemented) By filtering out messages that are not MAP messages, we can allow for processing of non-map messages via the current Asn1DecodedDataRouter paths while also allowing Asn1DecodedDataListener to process the MAP messages from the same topic (topic.Asn1DecoderOutput) * remove commented out code and update javadoc for filter strategy in KafkaConsumerConfig * remove routeMAP in favor of explicitly throwing UnsupportedDataTypeException * test application.yaml bootstrap-server port 9093->4242 to match tests * properly serialize data before publishing in Asn1DecodeMAPJSONListener * moved all TopicsTests under kafka.topics test package for consistency * moved Asn1DecodeMAPJSONTest to kafka package for consistency with what it's testing * use constructor injection instead of field injection AND constructor injection in Asn1DecodeMAPJSONListener * remove references to Asn1DecodeMAPJSON from Asn1DecodeMAPJSONTest to prepare for deletion of Asn1DecodeMAPJSON * delete Asn1DecodeMAPJSON.java and all references now that we've migrated to the Spring Kafka implementation for this data flow * only create one partition per topic in EmbeddedKafkaHolder * add Awaitility as test dependency to support async testing * replace EmbeddedKafka annotation with EmbeddedKafkaHolder for all Asn1Decode*JSONTests * delete obsolete AsnCodecMessageServiceControllerTest.java. Any test annotated with SpringBootTest will already confirm we can instantiate the AsnCodecMessageServiceController as expected * remove UnsupportedDataTypeException.java from consumption flows and let kafka's consumerGroups manage the separate offsets * inject test queue names with SpringBootTest annotation in Asn1DecodeMAPJSONTest to support unique test topic naming * inject test queue names with SpringBootTest annotation in MapReceiverTest to support unique test topic naming and port assignment * delete disabled AsnCodecRouterServiceControllerTest.java because bean instantiation is already tested by any SpringBootTest annotated tests * make OdeTimJsonTopology a spring Component and inject to properly manage streams lifecycle Before this change, whenever we would run any SpringBootTest tests in sequence we would get an INVALID_STATE error and fail tests unrelated to OdeTimJsonTopology. By turning the OdeTimJsonTopology into a Component we can allow Spring to manage the singleton lifecycle of the OdeTimJsonTopology and its kafka streams. * add consumer ids to listeners and move from property injection to constructor injection in Asn1DecodedDataListener * inject topic names into Asn1DecodedDataRouterApprovalTest to keep topics under test separate between tests * remove unnecessary annotations from Asn1DecodeMAPJSONTest * convert properties to local variable in OdeTimJsonTopology constructor * add KAFKA_TYPE env variable into OdeKafkaProperties * add ConfluentProperties to OdeKafkaProperties * default to empty string for kafkaType in OdeKafkaProperties to prevent NPE errors * replace OdeTimJsonTopology.java with Spring Kafka provided KStream via KafkaStreamConfig The Spring Kafka managed implementation provides SmartLifecycleManagement so that we don't need to manually manage the start/cleanup steps of the kstreams lifecycles. Before this implementation our SpringBootTest integration tests could not run in sequence because the streams would not be in a valid state between tests. * add confluent properties to the consumer and producer configuration conditionally * implement disabledTopic filtering in publish steps of Asn1DecodedDataListener and Asn1DecodeMAPJSONListener * correct indentation in TimDepositController * Revert "correct indentation in TimDepositController" This reverts commit d12d12c768fa4c52d8a2b1f7373f73184d3d1a7e. * Revert "replace OdeTimJsonTopology.java with Spring Kafka provided KStream via KafkaStreamConfig" This reverts commit 29a7fa1fa790fc9627cba01f2a942d6a3cd4cf24. * Revert "convert properties to local variable in OdeTimJsonTopology constructor" This reverts commit 9e2b332198f4dc82d6ab49561c4a169dddfe6705. * Revert "make OdeTimJsonTopology a spring Component and inject to properly manage streams lifecycle" This reverts commit 1427534907bde82aa0b1efa4dcf3ea1555e4df64. * make streams private final instead of static in OdeTimJsonTopology to better manage lifecycle * use OdeKafkaProperties.Confluent to set stream props for OdeTimJsonTopology to remove reliance on late stage props validation * make stream properties local to OdeTimJsonTopology constructor * pass in topic to OdeTimJsonTopology, add state listener, take start() internal * use Awaitility to await states in OdeTimJsonTopologyTest and remove testQuery as it is not unit testable; it requires an integration test with multiple kafka topic interactions * configure default timeout for Awaitility in Asn1DecodeMAPJSONTest to prevent flakiness * remove slf4j annotation from MessageProcessor where it is not needed * remove setStaticSchemaVersion from OdeProperties in favor of hard coding in OdeMsgMetadata for now * remove null string for key in send method Asn1DecodedDataListener * replace environment variable lookup with configuration value in OdeTimJsonTopology for kafkaType * deleted unnecessary OdePropertiesTest.java * reformat OdeKafkaPropertiesValidatorTest * correctly initialize embedded kafka and needed topics in Asn1Decode*JSONTest files * add missing confluent configuration to odeDatProducerFactory * add missing confluent configuration to odeDataConsumerFactory --- .../dot/its/jpo/ode/model/OdeMsgMetadata.java | 2 +- .../its/jpo/ode/wrapper/MessageProcessor.java | 8 +- jpo-ode-svcs/pom.xml | 6 + .../us/dot/its/jpo/ode/OdeProperties.java | 19 ++- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 67 +++------ .../jpo/ode/coder/FileAsn1CodecPublisher.java | 4 +- .../stream/LogFileToAsn1CodecPublisher.java | 4 +- .../importer/ImporterDirectoryWatcher.java | 4 +- .../jpo/ode/kafka/ConfluentProperties.java | 19 +++ .../jpo/ode/kafka/KafkaConsumerConfig.java | 114 +++++++++++++++ .../jpo/ode/kafka/KafkaProducerConfig.java | 53 +++++++ .../its/jpo/ode/kafka/OdeKafkaProperties.java | 2 + .../kafka/OdeKafkaPropertiesValidator.java | 15 ++ .../jpo/ode/kafka/XMLOdeObjectSerializer.java | 33 +++++ .../listeners/Asn1DecodeMAPJSONListener.java | 80 +++++++++++ .../listeners/Asn1DecodedDataListener.java | 82 +++++++++++ .../kafka/{ => topics}/Asn1CoderTopics.java | 2 +- .../ode/kafka/{ => topics}/FileTopics.java | 2 +- .../ode/kafka/{ => topics}/JsonTopics.java | 2 +- .../ode/kafka/{ => topics}/PojoTopics.java | 2 +- .../{ => topics}/RawEncodedJsonTopics.java | 2 +- .../{ => topics}/SDXDepositorTopics.java | 2 +- .../ode/services/asn1/Asn1CommandManager.java | 2 +- .../services/asn1/Asn1DecodedDataRouter.java | 20 +-- .../services/asn1/Asn1EncodedDataRouter.java | 11 +- .../asn1/AsnCodecRouterServiceController.java | 8 +- .../asn1/message/Asn1DecodeMAPJSON.java | 56 -------- .../AsnCodecMessageServiceController.java | 11 +- .../json/ToJsonServiceController.java | 4 +- .../ode/traveler/TimDepositController.java | 7 +- .../udp/controller/UdpServicesController.java | 7 +- .../jpo/ode/udp/generic/GenericReceiver.java | 2 +- .../dot/its/jpo/ode/udp/map/MapReceiver.java | 13 +- .../jpo/ode/upload/FileUploadController.java | 6 +- .../src/main/resources/application.yaml | 15 ++ .../us/dot/its/jpo/ode/OdePropertiesTest.java | 28 ---- .../its/jpo/ode/OdeTimJsonTopologyTest.java | 103 +++----------- .../LogFileToAsn1CodecPublisherTest.java | 4 +- .../ImporterDirectoryWatcherTest.java | 4 +- .../jpo/ode/kafka/Asn1DecodeMAPJSONTest.java | 79 +++++++++++ .../OdeKafkaPropertiesValidatorTest.java | 134 +++++++++++------- .../{ => topics}/Asn1CoderTopicsTest.java | 2 +- .../kafka/{ => topics}/FileTopicsTest.java | 2 +- .../kafka/{ => topics}/JsonTopicsTest.java | 2 +- .../kafka/{ => topics}/PojoTopicsTest.java | 2 +- .../RawEncodedJsonTopicsTest.java | 2 +- .../{ => topics}/SDXDepositorTopicsTest.java | 2 +- .../services/asn1/Asn1CommandManagerTest.java | 3 +- .../Asn1DecodedDataRouterApprovalTest.java | 88 +++++------- .../AsnCodecRouterServiceControllerTest.java | 59 -------- .../asn1/message/Asn1DecodeBSMJSONTest.java | 17 ++- .../asn1/message/Asn1DecodeMAPJSONTest.java | 112 --------------- .../asn1/message/Asn1DecodePSMJSONTest.java | 17 ++- .../asn1/message/Asn1DecodeSPATJSONTest.java | 19 ++- .../asn1/message/Asn1DecodeSRMJSONTest.java | 17 ++- .../asn1/message/Asn1DecodeSSMJSONTest.java | 17 ++- .../asn1/message/Asn1DecodeTIMJSONTest.java | 17 ++- .../AsnCodecMessageServiceControllerTest.java | 36 ----- .../json/ToJsonServiceControllerTest.java | 4 +- .../testUtilities/EmbeddedKafkaHolder.java | 30 ++++ .../traveler/TimDepositControllerTest.java | 6 +- .../TimIngestTrackerPropertiesTest.java | 2 +- .../its/jpo/ode/udp/map/MapReceiverTest.java | 86 ++++------- .../ode/upload/FileUploadControllerTest.java | 6 +- .../src/test/resources/application.yaml | 10 +- 65 files changed, 874 insertions(+), 722 deletions(-) create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/XMLOdeObjectSerializer.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/Asn1CoderTopics.java (90%) rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/FileTopics.java (89%) rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/JsonTopics.java (95%) rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/PojoTopics.java (93%) rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/RawEncodedJsonTopics.java (91%) rename jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/{ => topics}/SDXDepositorTopics.java (88%) delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/Asn1CoderTopicsTest.java (96%) rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/FileTopicsTest.java (96%) rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/JsonTopicsTest.java (98%) rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/PojoTopicsTest.java (98%) rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/RawEncodedJsonTopicsTest.java (97%) rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/{ => topics}/SDXDepositorTopicsTest.java (95%) delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeMsgMetadata.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeMsgMetadata.java index b0df065ad..30786379a 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeMsgMetadata.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeMsgMetadata.java @@ -31,7 +31,7 @@ public enum GeneratedBy { private static final long serialVersionUID = 3979762143291085955L; - private static int staticSchemaVersion; + private static int staticSchemaVersion = 7; private String payloadType; private SerialId serialId; diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProcessor.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProcessor.java index abf7be095..07627c4c8 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProcessor.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProcessor.java @@ -15,14 +15,14 @@ ******************************************************************************/ package us.dot.its.jpo.ode.wrapper; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.Callable; - import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.common.TopicPartition; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.Callable; + /** * @author 572682 * This abstract class provides the common and basic functionality for processinf messages diff --git a/jpo-ode-svcs/pom.xml b/jpo-ode-svcs/pom.xml index 1f8508542..e0fddf9ae 100644 --- a/jpo-ode-svcs/pom.xml +++ b/jpo-ode-svcs/pom.xml @@ -77,6 +77,12 @@ spring-kafka-test test + + org.awaitility + awaitility + 3.0.0 + test + org.webjars diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java index ffdf1784a..2876498cf 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeProperties.java @@ -18,31 +18,30 @@ import jakarta.annotation.PostConstruct; import lombok.Data; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.info.BuildProperties; -import org.springframework.context.annotation.Configuration; -import us.dot.its.jpo.ode.model.OdeMsgMetadata; +import org.springframework.context.annotation.Import; +import org.springframework.stereotype.Component; -@Configuration -@ConfigurationProperties(prefix = "ode") +@Component @Data @Slf4j +@Import(BuildProperties.class) public class OdeProperties { - private int outputSchemaVersion = 7; private static final byte[] JPO_ODE_GROUP_ID = "jode".getBytes(); - @Autowired - BuildProperties buildProperties; + final BuildProperties buildProperties; + + public OdeProperties(BuildProperties buildProperties) { + this.buildProperties = buildProperties; + } @PostConstruct void initialize() { log.info("groupId: {}", buildProperties.getGroup()); log.info("artifactId: {}", buildProperties.getArtifact()); log.info("version: {}", buildProperties.getVersion()); - OdeMsgMetadata.setStaticSchemaVersion(this.outputSchemaVersion); } public String getVersion() { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index 76ebb2197..8ae4f1178 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -23,71 +23,42 @@ @Slf4j public class OdeTimJsonTopology { + private final KafkaStreams streams; - private final Properties streamsProperties = new Properties(); - static KafkaStreams streams; + public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps, String topic) { - public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps) { - if (odeKafkaProps.getBrokers() != null) { - this.streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); - this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); - this.streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass()); - this.streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass()); - - String kafkaType = System.getenv("KAFKA_TYPE"); - if (kafkaType != null && kafkaType.equals("CONFLUENT")) { - addConfluentProperties(this.streamsProperties); - } - } else { - log.error("Kafka Brokers not set in OdeProperties"); - } - } + Properties streamsProperties = new Properties(); + streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); + streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); + streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); + streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); - public void start() { - if (streams != null && streams.state().isRunningOrRebalancing()) { - throw new IllegalStateException("Start called while streams is already running."); - } else { - if (streams == null) { - streams = new KafkaStreams(buildTopology(), streamsProperties); - } - log.info("Starting Ode Tim Json Topology"); - streams.start(); + if ("CONFLUENT".equals(odeKafkaProps.getKafkaType())) { + streamsProperties.put("sasl.jaas.config", odeKafkaProps.getConfluent().getSaslJaasConfig()); } + streams = new KafkaStreams(buildTopology(topic), streamsProperties); + streams.setStateListener((newState, oldState) -> + log.info("Transitioning from {} to {}", oldState, newState) + ); + streams.start(); } public void stop() { - if (streams != null) { - log.info("Stopping Ode Tim Json Topology"); - streams.close(); - } + log.info("Stopping Ode Tim Json Topology"); + streams.close(); } public boolean isRunning() { - return streams != null && streams.state().isRunningOrRebalancing(); + return streams.state().isRunningOrRebalancing(); } - public Topology buildTopology() { + public Topology buildTopology(String topic) { StreamsBuilder builder = new StreamsBuilder(); - builder.table("topic.OdeTimJson", Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); + builder.table(topic, Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); return builder.build(); } public String query(String uuid) { return (String) streams.store(StoreQueryParameters.fromNameAndType("timjson-store", QueryableStoreTypes.keyValueStore())).get(uuid); } - - private void addConfluentProperties(Properties properties) { - String username = System.getenv("CONFLUENT_KEY"); - String password = System.getenv("CONFLUENT_SECRET"); - - if (username != null && password != null) { - String auth = "org.apache.kafka.common.security.plain.PlainLoginModule required " + - "username=\"" + username + "\" " + - "password=\"" + password + "\";"; - this.streamsProperties.put("sasl.jaas.config", auth); - } - else { - log.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); - } - } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index 7852e75e4..9d40bee16 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -18,9 +18,9 @@ import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.stream.LogFileToAsn1CodecPublisher; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import java.io.BufferedInputStream; import java.nio.file.Path; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java index 1f6bda2fc..0e570ef62 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisher.java @@ -20,8 +20,8 @@ import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; import us.dot.its.jpo.ode.importer.parser.*; import us.dot.its.jpo.ode.importer.parser.FileParser.ParserStatus; -import us.dot.its.jpo.ode.kafka.JsonTopics; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.uper.UperUtil; import us.dot.its.jpo.ode.util.JsonUtils; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java index 13c87f0c4..bb68152ed 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcher.java @@ -20,9 +20,9 @@ import lombok.extern.slf4j.Slf4j; import us.dot.its.jpo.ode.coder.FileAsn1CodecPublisher; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import java.io.IOException; import java.nio.file.Path; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java new file mode 100644 index 000000000..25d082cff --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java @@ -0,0 +1,19 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "ode.kafka.confluent") +@Data +public class ConfluentProperties { + private String username; + private String password; + + public String getSaslJaasConfig() { + return "org.apache.kafka.common.security.plain.PlainLoginModule required " + + "username=\"" + username + "\" " + + "password=\"" + password + "\";"; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java new file mode 100644 index 000000000..57ce997c6 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java @@ -0,0 +1,114 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.json.JSONObject; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; +import org.springframework.kafka.core.ConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.listener.adapter.RecordFilterStrategy; +import org.springframework.kafka.support.serializer.JsonDeserializer; +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.model.OdeAsn1Data; +import us.dot.its.jpo.ode.model.OdeMapData; +import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; +import us.dot.its.jpo.ode.util.XmlUtils; + +import java.util.HashMap; +import java.util.Map; + +@EnableKafka +@Configuration +@Slf4j +public class KafkaConsumerConfig { + + private final KafkaProperties kafkaProperties; + private final OdeKafkaProperties odeKafkaProperties; + + public KafkaConsumerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties odeKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.odeKafkaProperties = odeKafkaProperties; + } + + @Bean + public ConsumerFactory consumerFactory() { + var consumerProps = kafkaProperties.buildConsumerProperties(); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + consumerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); + } + return new DefaultKafkaConsumerFactory<>(consumerProps); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } + + @Bean + public ConsumerFactory odeMapDataConsumerFactory() { + Map props = new HashMap<>(kafkaProperties.buildConsumerProperties()); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + props.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); + } + return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(OdeMapData.class)); + } + + @Bean + public ConcurrentKafkaListenerContainerFactory odeMapDataConsumerListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(odeMapDataConsumerFactory()); + return factory; + } + + /** + * @return factory A listener factory that supports filtering out messages that don't match a specific pattern + *

+ * @deprecated This method is intended to be short-lived. It exists to allow consumption via the Asn1DecodedDataRouter & + * the Asn1DecodedDataListener while we are migrating from hand-rolled Kafka implementation to Spring's Kafka implementation + */ + @Bean + @Deprecated(forRemoval = true) + public ConcurrentKafkaListenerContainerFactory tempFilteringKafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + factory.setRecordFilterStrategy(getFilterStrategySpringKafkaSupportedMessageTypesOnly()); + + return factory; + } + + /** + * While migrating to Spring Kafka the consumers provided from this factory will only consume (and ack) messages + * we support via the Spring Kafka implementation. All other messages will be handled by the Asn1DecodedDataRouter + * + * @return RecordFilterStrategy filter + */ + private static RecordFilterStrategy getFilterStrategySpringKafkaSupportedMessageTypesOnly() { + return consumerRecord -> { + try { + JSONObject consumed = XmlUtils.toJSONObject(consumerRecord.value()).getJSONObject(OdeAsn1Data.class.getSimpleName()); + + J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( + consumed.getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING) + .getJSONObject("MessageFrame") + .getInt("messageId") + ); + + // Filter out all messages EXCEPT for MAP messages + return !J2735DSRCmsgID.MAPMessage.equals(messageId); + } catch (XmlUtils.XmlUtilsException e) { + log.warn("Unable to parse JSON object", e); + return false; + } catch (Exception e) { + log.warn("Failed to detect message ID", e); + return false; + } + }; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java new file mode 100644 index 000000000..649a6f585 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.kafka; + +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import us.dot.its.jpo.ode.model.OdeObject; + +@EnableKafka +@Configuration +public class KafkaProducerConfig { + + private final KafkaProperties kafkaProperties; + private final OdeKafkaProperties odeKafkaProperties; + + public KafkaProducerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties odeKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.odeKafkaProperties = odeKafkaProperties; + } + + @Bean + public ProducerFactory producerFactory() { + var producerProps = kafkaProperties.buildProducerProperties(); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); + } + return new DefaultKafkaProducerFactory<>(producerProps); + } + + @Bean + public KafkaTemplate kafkaTemplate() { + return new KafkaTemplate<>(producerFactory()); + } + + @Bean + public ProducerFactory odeDataProducerFactory() { + var producerProps = kafkaProperties.buildProducerProperties(); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); + } + return new DefaultKafkaProducerFactory<>(producerProps, + new StringSerializer(), new XMLOdeObjectSerializer()); + } + + @Bean + public KafkaTemplate odeDataKafkaTemplate() { + return new KafkaTemplate<>(odeDataProducerFactory()); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java index cd79ce198..0e7225d83 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaProperties.java @@ -16,6 +16,8 @@ public class OdeKafkaProperties { private String brokers; private Set disabledTopics; private Producer producer; + private String kafkaType = ""; + private ConfluentProperties confluent; @Data public static class Producer { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java index da11e5e33..01bbcb866 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidator.java @@ -7,6 +7,7 @@ public class OdeKafkaPropertiesValidator implements Validator { private static final List VALID_ACKS = List.of("all", "0", "1", "-1"); + private static final List VALID_KAFKA_TYPES = List.of("", "CONFLUENT"); @Override public boolean supports(Class clazz) { @@ -28,5 +29,19 @@ public void validate(Object target, org.springframework.validation.Errors errors errors.rejectValue("brokers", "broker must be in the format host:port"); } } + + if (!VALID_KAFKA_TYPES.contains(properties.getKafkaType())) { + errors.rejectValue("kafkaType", "type value must be one of: " + VALID_KAFKA_TYPES); + } + + if ("CONFLUENT".equals(properties.getKafkaType())) { + ConfluentProperties confluent = properties.getConfluent(); + if (confluent.getPassword() == null) { + errors.rejectValue("confluent.password", "when kafka-type is set to CONFLUENT the password must be set"); + } + if (confluent.getUsername() == null) { + errors.rejectValue("confluent.username", "when kafka-type is set to CONFLUENT the username must be set"); + } + } } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/XMLOdeObjectSerializer.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/XMLOdeObjectSerializer.java new file mode 100644 index 000000000..1a21edb9b --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/XMLOdeObjectSerializer.java @@ -0,0 +1,33 @@ +package us.dot.its.jpo.ode.kafka; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import org.apache.kafka.common.errors.SerializationException; +import org.apache.kafka.common.serialization.Serializer; +import us.dot.its.jpo.ode.model.OdeObject; + +public class XMLOdeObjectSerializer implements Serializer { + + private final XmlMapper xmlMapper; + + public XMLOdeObjectSerializer() { + var builder = new XmlMapper.Builder(new XmlMapper()); + builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + builder.defaultUseWrapper(true); + xmlMapper = builder.build(); + } + + @Override + public byte[] serialize(String s, OdeObject data) { + try { + if (data == null) { + return new byte[0]; + } else { + return xmlMapper.writeValueAsBytes(data); + } + } catch (JsonProcessingException e) { + throw new SerializationException("Error when serializing object to XML byte[]", e); + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java new file mode 100644 index 000000000..6b85b0dde --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java @@ -0,0 +1,80 @@ +package us.dot.its.jpo.ode.kafka.listeners; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; +import org.json.JSONObject; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.annotation.KafkaHandler; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.model.Asn1Encoding; +import us.dot.its.jpo.ode.model.OdeAsn1Data; +import us.dot.its.jpo.ode.model.OdeAsn1Payload; +import us.dot.its.jpo.ode.model.OdeMapMetadata; +import us.dot.its.jpo.ode.model.OdeObject; +import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; +import us.dot.its.jpo.ode.uper.SupportedMessageType; +import us.dot.its.jpo.ode.uper.UperUtil; + +import java.util.Set; + +@Slf4j +@Component +@KafkaListener(id = "Asn1DecodeMAPJSONListener", topics = "${ode.kafka.topics.raw-encoded-json.map}") +public class Asn1DecodeMAPJSONListener { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + private final String publishTopic; + private final KafkaTemplate kafkaTemplate; + private final Set disabledTopics; + + public Asn1DecodeMAPJSONListener(KafkaTemplate kafkaTemplate, + @Value("${ode.kafka.topics.asn1.decoder-input}") String publishTopic, + OdeKafkaProperties odeKafkaProperties) { + this.kafkaTemplate = kafkaTemplate; + this.publishTopic = publishTopic; + this.disabledTopics = odeKafkaProperties.getDisabledTopics(); + } + + @KafkaHandler + public void listen(String consumedData) throws JsonProcessingException, StartFlagNotFoundException { + log.debug("consumedData: {}", consumedData); + JSONObject rawMapJsonObject = new JSONObject(consumedData); + + String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); + OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); + + Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", Asn1Encoding.EncodingRule.UPER); + metadata.addEncoding(unsecuredDataEncoding); + + String payloadHexString = ((JSONObject) ((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); + payloadHexString = UperUtil.stripDot2Header(payloadHexString, SupportedMessageType.MAP.getStartFlag()); + + OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + + OdeAsn1Data data = new OdeAsn1Data(metadata, payload); + send(data); + } + + private void send(OdeObject odeObject) { + if (disabledTopics.contains(publishTopic)) { + log.debug("Topic {} is disabled. Skipping sending message.", publishTopic); + return; + } + var future = kafkaTemplate.send(publishTopic, odeObject); + + future.whenComplete((result, ex) -> { + if (ex != null) { + log.error(ex.getMessage(), ex); + } else { + log.debug("Successfully sent message to topic {} with offset {} on partition {}", + publishTopic, result.getRecordMetadata().offset(), result.getRecordMetadata().partition()); + } + }); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java new file mode 100644 index 000000000..d44aabe76 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java @@ -0,0 +1,82 @@ +package us.dot.its.jpo.ode.kafka.listeners; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.annotation.KafkaHandler; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.messaging.handler.annotation.Headers; +import org.springframework.messaging.handler.annotation.Payload; +import org.springframework.stereotype.Component; +import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.model.OdeAsn1Data; +import us.dot.its.jpo.ode.model.OdeLogMetadata; +import us.dot.its.jpo.ode.util.XmlUtils; + +import java.util.Map; +import java.util.Set; + +@Slf4j +@Component +@KafkaListener(id = "Asn1DecodedDataListener", topics = "${ode.kafka.topics.asn1.decoder-output}", containerFactory = "tempFilteringKafkaListenerContainerFactory") +public class Asn1DecodedDataListener { + + + private final String jsonMapTopic; + private final String pojoTxMapTopic; + private final KafkaTemplate kafkaTemplate; + private final Set disabledTopics; + + public Asn1DecodedDataListener(KafkaTemplate kafkaTemplate, + @Value("${ode.kafka.topics.pojo.tx-map}") String pojoTxMapTopic, + @Value("${ode.kafka.topics.json.map}") String jsonMapTopic, + OdeKafkaProperties odeKafkaProperties) { + this.kafkaTemplate = kafkaTemplate; + this.pojoTxMapTopic = pojoTxMapTopic; + this.jsonMapTopic = jsonMapTopic; + this.disabledTopics = odeKafkaProperties.getDisabledTopics(); + } + + @KafkaHandler + public void listenToMAPs(@Headers Map keys, @Payload String payload) { + log.debug("Key: {} payload: {}", keys, payload); + try { + String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(payload).toString(); + + OdeLogMetadata.RecordType recordType = OdeLogMetadata.RecordType + .valueOf(XmlUtils.toJSONObject(payload) + .getJSONObject(OdeAsn1Data.class.getSimpleName()) + .getJSONObject(AppContext.METADATA_STRING) + .getString("recordType") + ); + if (recordType == OdeLogMetadata.RecordType.mapTx) { + log.debug("Publishing message with recordType: {} to {} ", recordType, pojoTxMapTopic); + send(odeMapData, pojoTxMapTopic); + } + + // Send all MAP data to OdeMapJson despite the record type + send(odeMapData, jsonMapTopic); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + } + + private void send(String odeMapData, String publishTopic) { + if (disabledTopics.contains(publishTopic)) { + log.debug("Topic {} is disabled. Skipping sending message.", publishTopic); + return; + } + + var future = kafkaTemplate.send(publishTopic, odeMapData); + future.whenComplete((result, ex) -> { + if (ex != null) { + log.error(ex.getMessage(), ex); + } else { + log.debug("Successfully sent message to topic {} with offset {} on partition {}", + publishTopic, result.getRecordMetadata().offset(), result.getRecordMetadata().partition()); + } + }); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopics.java similarity index 90% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopics.java index d2d614f2a..c19fc24e5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/FileTopics.java similarity index 89% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/FileTopics.java index 531e35100..a581f619f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/FileTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/FileTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/JsonTopics.java similarity index 95% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/JsonTopics.java index a6f7cca0d..b6939ecda 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/JsonTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/JsonTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/PojoTopics.java similarity index 93% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/PojoTopics.java index 52e2da854..55c4b84c3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/PojoTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/PojoTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopics.java similarity index 91% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopics.java index cd421da2e..dc38c68d3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopics.java similarity index 88% rename from jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java rename to jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopics.java index 8312d65f1..d98e76e8b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopics.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopics.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index a8bdd7c3f..fa2af8bde 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -26,7 +26,7 @@ import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; +import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsdPayload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index af8809864..5189f40f8 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -19,9 +19,9 @@ import org.json.JSONObject; import us.dot.its.jpo.ode.coder.*; import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; @@ -40,7 +40,6 @@ public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor bsmProducer; private final MessageProducer timProducer; private final MessageProducer spatProducer; - private final MessageProducer mapProducer; private final MessageProducer ssmProducer; private final MessageProducer srmProducer; private final MessageProducer psmProducer; @@ -61,9 +60,6 @@ public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics p this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); - this.mapProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), - odeKafkaProperties.getDisabledTopics()); this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); @@ -93,7 +89,7 @@ public Object process(String consumedData) { case BasicSafetyMessage -> routeBSM(consumedData, recordType); case TravelerInformation -> routeTIM(consumed, recordType); case SPATMessage -> routeSPAT(consumedData, recordType); - case MAPMessage -> routeMAP(consumedData, recordType); + case MAPMessage -> log.debug("MAP data processing no longer supported in this router."); case SSMMessage -> routeSSM(consumedData, recordType); case SRMMessage -> routeSRM(consumedData, recordType); case PersonalSafetyMessage -> routePSM(consumedData, recordType); @@ -135,16 +131,6 @@ private void routeSSM(String consumedData, RecordType recordType) throws XmlUtil log.debug("Submitted to SSM Pojo topic {}", jsonTopics.getSsm()); } - private void routeMAP(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(consumedData).toString(); - if (recordType == RecordType.mapTx) { - mapProducer.send(pojoTopics.getTxMap(), getRecord().key(), odeMapData); - } - // Send all Map also to OdeMapJson - mapProducer.send(jsonTopics.getMap(), getRecord().key(), odeMapData); - log.debug("Submitted to MAP Pojo topic {}", jsonTopics.getMap()); - } - private void routeSPAT(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); switch (recordType) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index e12831bfe..57b7a9aee 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -22,10 +22,10 @@ import us.dot.its.jpo.ode.OdeTimJsonTopology; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; +import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.rsu.RsuProperties; @@ -86,10 +86,7 @@ public Asn1EncodedDataRouter(OdeKafkaProperties odeKafkaProperties, this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); this.dataSigningEnabledRSU = securityServicesProperties.getIsRsuSigningEnabled(); - odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties); - if (!odeTimJsonTopology.isRunning()) { - odeTimJsonTopology.start(); - } + odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties, jsonTopics.getTim()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index ab8cc3227..ab1a84898 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -18,11 +18,11 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.security.SecurityServicesProperties; import us.dot.its.jpo.ode.wrapper.MessageConsumer; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java deleted file mode 100644 index c890b8293..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSON.java +++ /dev/null @@ -1,56 +0,0 @@ -package us.dot.its.jpo.ode.services.asn1.message; - -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.extern.slf4j.Slf4j; -import org.apache.tomcat.util.buf.HexUtils; -import org.json.JSONObject; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.model.Asn1Encoding; -import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeMapMetadata; -import us.dot.its.jpo.ode.uper.StartFlagNotFoundException; -import us.dot.its.jpo.ode.uper.SupportedMessageType; -import us.dot.its.jpo.ode.uper.UperUtil; - -@Slf4j -public class Asn1DecodeMAPJSON extends AbstractAsn1DecodeMessageJSON { - private final ObjectMapper objectMapper = new ObjectMapper(); - - public Asn1DecodeMAPJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super( - publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), - SupportedMessageType.MAP.getStartFlag() - ); - } - - @Override - protected OdeAsn1Data process(String consumedData) { - OdeAsn1Data messageToPublish = null; - try { - JSONObject rawMapJsonObject = new JSONObject(consumedData); - - String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); - OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); - - Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", EncodingRule.UPER); - metadata.addEncoding(unsecuredDataEncoding); - - String payloadHexString = ((JSONObject) ((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, super.payloadStartFlag); - - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - - messageToPublish = new OdeAsn1Data(metadata, payload); - publishEncodedMessageToAsn1Decoder(messageToPublish); - } catch (StartFlagNotFoundException e) { - log.error("Unexpected data type encountered.", e); - } catch (Exception e) { - log.error("Error publishing to Asn1DecoderInput: {}", e.getMessage()); - } - return messageToPublish; - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java index ecee22a05..ea692daa1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceController.java @@ -3,9 +3,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; /*** @@ -61,13 +61,6 @@ public AsnCodecMessageServiceController(OdeKafkaProperties odeKafkaProperties, R asn1RawTIMJSONConsumer.setName("asn1DecodeTIMJSON"); asn1DecodeTIMJSON.start(asn1RawTIMJSONConsumer, rawEncodedJsonTopics.getTim()); - log.info("Send encoded MAP to ASN.1 Decoder"); - Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); - asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSON"); - asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, rawEncodedJsonTopics.getMap()); - log.info("Send encoded PSM to ASN.1 Decoder"); Asn1DecodePSMJSON asn1DecodePSMSON = new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); MessageConsumer asn1RawPSMJSONConsumer = MessageConsumer.defaultStringMessageConsumer( diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java index 0773d030f..77f0f79e8 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonServiceController.java @@ -18,9 +18,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.serdes.OdeBsmDeserializer; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 5062017cc..07bea3cf4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -23,10 +23,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; import us.dot.its.jpo.ode.model.*; import us.dot.its.jpo.ode.plugin.ServiceRequest; @@ -44,7 +44,6 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeTimSerializer; -import java.util.UUID; import java.text.ParseException; import java.text.SimpleDateFormat; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index 882aaa354..097fdbb07 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -2,9 +2,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Controller; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; 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; @@ -22,7 +23,7 @@ public class UdpServicesController { @Autowired - public UdpServicesController(UDPReceiverProperties udpProps, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { + public UdpServicesController(UDPReceiverProperties udpProps, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics, KafkaTemplate kafkaTemplate) { super(); ServiceManager rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); @@ -33,7 +34,7 @@ public UdpServicesController(UDPReceiverProperties udpProps, OdeKafkaProperties rm.submit(new SsmReceiver(udpProps.getSsm(), odeKafkaProperties, rawEncodedJsonTopics.getSsm())); rm.submit(new SrmReceiver(udpProps.getSrm(), odeKafkaProperties, rawEncodedJsonTopics.getSrm())); rm.submit(new SpatReceiver(udpProps.getSpat(), odeKafkaProperties, rawEncodedJsonTopics.getSpat())); - rm.submit(new MapReceiver(udpProps.getMap(), odeKafkaProperties, rawEncodedJsonTopics.getMap())); + rm.submit(new MapReceiver(udpProps.getMap(), kafkaTemplate, rawEncodedJsonTopics.getMap())); rm.submit(new PsmReceiver(udpProps.getPsm(), odeKafkaProperties, rawEncodedJsonTopics.getPsm())); rm.submit(new GenericReceiver(udpProps.getGeneric(), odeKafkaProperties, rawEncodedJsonTopics)); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index a65918d60..e5130debd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -4,7 +4,7 @@ import org.apache.tomcat.util.buf.HexUtils; import us.dot.its.jpo.ode.coder.StringPublisher; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index bd6084f38..ab70c7269 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -1,8 +1,7 @@ package us.dot.its.jpo.ode.udp.map; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; @@ -12,14 +11,14 @@ @Slf4j public class MapReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher mapPublisher; + + KafkaTemplate kafkaTemplate; private final String publishTopic; - public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { + public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - + this.kafkaTemplate = kafkaTemplate; this.publishTopic = publishTopic; - this.mapPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); } @Override @@ -35,7 +34,7 @@ public void run() { if (packet.getLength() > 0) { String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); if (mapJson != null) { - mapPublisher.publish(this.publishTopic, mapJson); + kafkaTemplate.send(publishTopic, mapJson); } } else { log.debug("Ignoring empty packet from {}", packet.getSocketAddress()); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java index a69b84779..e3cea1aa9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/upload/FileUploadController.java @@ -25,10 +25,10 @@ import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.exporter.StompStringExporter; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; -import us.dot.its.jpo.ode.kafka.FileTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.FileTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; import us.dot.its.jpo.ode.storage.StorageService; diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index f6418668d..ed75da618 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -1,4 +1,18 @@ spring: + application: + name: "jpo-ode-svcs" + kafka: + consumer: + enable-auto-commit: true + auto-commit-interval: 1000 + bootstrap-servers: ${DOCKER_HOST_IP}:9092 + producer: + acks: "all" + retries: 0 + batch-size: 16384 + compression-type: "zstd" + buffer-memory: 33554432 + bootstrap-servers: ${DOCKER_HOST_IP}:9092 http: multipart: max-file-size: 1MB @@ -17,6 +31,7 @@ ode: password: ${RSU_PASSWORD} kafka: brokers: ${DOCKER_HOST_IP}:9092 + kafka-type: ${KAFKA_TYPE} producer: type: "sync" acks: ${KAFKA_ACKS} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java deleted file mode 100644 index f87c1c42b..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdePropertiesTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package us.dot.its.jpo.ode; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.info.BuildProperties; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@Import({BuildProperties.class}) -@EnableConfigurationProperties(value = {OdeProperties.class, org.springframework.boot.info.BuildProperties.class}) -class OdePropertiesTest { - - @Autowired - OdeProperties testOdeProperties; - - @Test - void testOutputSchemaVersion() { - assertEquals(7, testOdeProperties.getOutputSchemaVersion()); - } -} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java index 4582344fd..32017ef36 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/OdeTimJsonTopologyTest.java @@ -1,108 +1,47 @@ package us.dot.its.jpo.ode; -import org.apache.kafka.streams.KafkaStreams; -import org.apache.kafka.streams.StoreQueryParameters; -import org.apache.kafka.streams.Topology; -import org.apache.kafka.streams.state.ReadOnlyKeyValueStore; -import org.junit.jupiter.api.AfterEach; +import org.awaitility.Awaitility; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - +@ExtendWith(SpringExtension.class) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@EnableConfigurationProperties(value = OdeKafkaProperties.class) class OdeTimJsonTopologyTest { + @Autowired + private OdeKafkaProperties odeKafkaProperties; + + @Value("${ode.kafka.topics.json.tim}") + private String timTopic; + private OdeTimJsonTopology odeTimJsonTopology; - private KafkaStreams mockStreams; - private ReadOnlyKeyValueStore mockStore; - private OdeKafkaProperties mockOdeKafkaProps; @BeforeEach void setUp() throws SecurityException, IllegalArgumentException { - mockOdeKafkaProps = mock(OdeKafkaProperties.class); - odeTimJsonTopology = new OdeTimJsonTopology(mockOdeKafkaProps); - mockStreams = mock(KafkaStreams.class); - mockStore = mock(ReadOnlyKeyValueStore.class); - - OdeTimJsonTopology.streams = mockStreams; - } - - @AfterEach - void tearDown() { - OdeTimJsonTopology.streams = null; - } - - @Test - void testStart() { - when(mockStreams.state()).thenReturn(KafkaStreams.State.NOT_RUNNING); - doNothing().when(mockStreams).start(); - - odeTimJsonTopology.start(); - - verify(mockStreams).start(); - } - - @Test - void testStartWhenAlreadyRunning() { - when(mockStreams.state()).thenReturn(KafkaStreams.State.RUNNING); - - IllegalStateException exception = assertThrows(IllegalStateException.class, () -> { - odeTimJsonTopology.start(); - }); - - assertEquals("Start called while streams is already running.", exception.getMessage()); + odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties, timTopic); + Awaitility.setDefaultTimeout(250, java.util.concurrent.TimeUnit.MILLISECONDS); } @Test void testStop() { - doNothing().when(mockStreams).close(); - odeTimJsonTopology.stop(); - - verify(mockStreams).close(); + Awaitility.await().untilAsserted(() -> assertFalse(odeTimJsonTopology.isRunning())); } @Test void testIsRunning() { - when(mockStreams.state()).thenReturn(KafkaStreams.State.RUNNING); - - assertTrue(odeTimJsonTopology.isRunning()); - } - - @Test - void testIsNotRunning() { - when(mockStreams.state()).thenReturn(KafkaStreams.State.NOT_RUNNING); - - assertFalse(odeTimJsonTopology.isRunning()); - } - - @Test - void testBuildTopology() { - Topology topology = odeTimJsonTopology.buildTopology(); - assertNotNull(topology); - } - - @Test - void testQuery() { - String uuid = "test-uuid"; - String expectedValue = "test-value"; - - when(mockStreams.store(any(StoreQueryParameters.class))).thenReturn(mockStore); - when(mockStore.get(uuid)).thenReturn(expectedValue); - - String result = odeTimJsonTopology.query(uuid); - - assertEquals(expectedValue, result); + Awaitility.await().untilAsserted(() -> assertTrue(odeTimJsonTopology.isRunning())); } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java index e42fa2a9f..1f1d78e1e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/stream/LogFileToAsn1CodecPublisherTest.java @@ -26,8 +26,8 @@ import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher.ImporterFileType; import us.dot.its.jpo.ode.importer.parser.FileParser.ParserStatus; import us.dot.its.jpo.ode.importer.parser.LogFileParser; -import us.dot.its.jpo.ode.kafka.JsonTopics; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeData; import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; import us.dot.its.jpo.ode.model.OdeMsgMetadata; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java index c8165532a..0fd50ed53 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/importer/ImporterDirectoryWatcherTest.java @@ -23,9 +23,9 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import java.nio.file.Files; import java.nio.file.Path; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java new file mode 100644 index 000000000..6ed4e2c9a --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java @@ -0,0 +1,79 @@ +package us.dot.its.jpo.ode.kafka; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.Consumer; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.clients.producer.Producer; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; + +@Slf4j +@SpringBootTest(properties = {"ode.kafka.topics.raw-encoded-json.map=topic.Asn1DecoderTestMAPJSON", + "ode.kafka.topics.asn1.decoder-input=topic.Asn1DecoderMAPInput"}) +@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@DirtiesContext +class Asn1DecodeMAPJSONTest { + + @Value(value = "${ode.kafka.topics.raw-encoded-json.map}") + private String rawEncodedMapJson; + + @Value(value = "${ode.kafka.topics.asn1.decoder-input}") + private String asn1DecoderInput; + + private static final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testProcess_ApprovalTest() throws IOException { + Awaitility.setDefaultTimeout(250, java.util.concurrent.TimeUnit.MILLISECONDS); + try { + EmbeddedKafkaHolder.getEmbeddedKafka().addTopics( + new NewTopic(rawEncodedMapJson, 1, (short) 1), + new NewTopic(asn1DecoderInput, 1, (short) 1) + ); + } catch (Exception e) { + log.warn("New topics not created: {}", e.getMessage()); + } + + String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; + List approvalTestCases = deserializeTestCases(path); + + Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); + DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); + Producer producer = producerFactory.createProducer(); + + Map consumerProps = KafkaTestUtils.consumerProps(this.getClass().getSimpleName(), "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer testConsumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, asn1DecoderInput); + + for (ApprovalTestCase approvalTestCase : approvalTestCases) { + // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer + ProducerRecord r = new ProducerRecord<>(rawEncodedMapJson, approvalTestCase.getInput()); + var sent = producer.send(r); + Awaitility.await().until(sent::isDone); + + ConsumerRecord actualRecord = KafkaTestUtils.getSingleRecord(testConsumer, asn1DecoderInput); + assertEquals(approvalTestCase.getExpected(), actualRecord.value(), approvalTestCase.getDescription()); + } + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java index 09e1bda95..1e4721b90 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/OdeKafkaPropertiesValidatorTest.java @@ -6,55 +6,87 @@ class OdeKafkaPropertiesValidatorTest { - @Test - void supports() { - OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); - assertTrue(validator.supports(OdeKafkaProperties.class)); - assertFalse(validator.supports(Object.class)); - } - - @Test - void validate() { - OdeKafkaProperties properties = new OdeKafkaProperties(); - properties.setBrokers("localhost:9092"); - OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); - producer.setAcks("all"); - properties.setProducer(producer); - - OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); - org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); - validator.validate(properties, errors); - - assertFalse(errors.hasErrors()); - } - - @Test - void errorThrownForInvalidAcks() { - OdeKafkaProperties properties = new OdeKafkaProperties(); - properties.setBrokers("localhost:9092"); - OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); - producer.setAcks("none"); - properties.setProducer(producer); - - OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); - org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); - validator.validate(properties, errors); - - assertTrue(errors.hasErrors()); - } - - @Test - void errorThrownForInvalidBrokers() { - OdeKafkaProperties properties = new OdeKafkaProperties(); - properties.setBrokers(""); - OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); - producer.setAcks("all"); - properties.setProducer(producer); - - OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); - org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); - validator.validate(properties, errors); - - assertTrue(errors.hasErrors()); - } + @Test + void supports() { + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + assertTrue(validator.supports(OdeKafkaProperties.class)); + assertFalse(validator.supports(Object.class)); + } + + @Test + void validate() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers("localhost:9092"); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("all"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertFalse(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidAcks() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers("localhost:9092"); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("none"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidBrokers() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + properties.setBrokers(""); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + producer.setAcks("all"); + properties.setProducer(producer); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + } + + @Test + void errorThrownForInvalidKafkaType() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + properties.setProducer(producer); + properties.setKafkaType("REDPANDA"); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + + assertTrue(errors.hasErrors()); + assertNotNull(errors.getFieldError("kafkaType")); + } + + @Test + void errorThrownForInvalidConfluentProperties() { + OdeKafkaProperties properties = new OdeKafkaProperties(); + OdeKafkaProperties.Producer producer = new OdeKafkaProperties.Producer(); + properties.setProducer(producer); + properties.setKafkaType("CONFLUENT"); + ConfluentProperties confluentProperties = new ConfluentProperties(); + properties.setConfluent(confluentProperties); + + OdeKafkaPropertiesValidator validator = new OdeKafkaPropertiesValidator(); + org.springframework.validation.BeanPropertyBindingResult errors = new org.springframework.validation.BeanPropertyBindingResult(properties, "properties"); + validator.validate(properties, errors); + assertTrue(errors.hasErrors()); + assertNotNull(errors.getFieldError("confluent.password")); + assertNotNull(errors.getFieldError("confluent.username")); + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopicsTest.java similarity index 96% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopicsTest.java index de151d0b5..157a6cee7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1CoderTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/Asn1CoderTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/FileTopicsTest.java similarity index 96% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/FileTopicsTest.java index b056fa233..75b165ad8 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/FileTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/FileTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/JsonTopicsTest.java similarity index 98% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/JsonTopicsTest.java index 033edcc14..cfae2811c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/JsonTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/JsonTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/PojoTopicsTest.java similarity index 98% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/PojoTopicsTest.java index 3a6d325a4..dbda84a6b 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/PojoTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/PojoTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopicsTest.java similarity index 97% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopicsTest.java index afd023c6f..827c40a5f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/RawEncodedJsonTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/RawEncodedJsonTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopicsTest.java similarity index 95% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopicsTest.java index df6cb08fa..bc700a7dd 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/SDXDepositorTopicsTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/topics/SDXDepositorTopicsTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.kafka; +package us.dot.its.jpo.ode.kafka.topics; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java index 11b152d47..46474407d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManagerTest.java @@ -26,8 +26,7 @@ import mockit.Mocked; import mockit.Tested; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; -import us.dot.its.jpo.ode.kafka.SDXDepositorTopics; +import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeTravelerInputData; import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.security.SecurityServicesProperties; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java index acf13eecb..c51539e82 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java @@ -1,30 +1,23 @@ package us.dot.its.jpo.ode.services.asn1; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka.clients.producer.ProducerRecord; +import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.test.EmbeddedKafkaBroker; -import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeMapData; import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; -import us.dot.its.jpo.ode.wrapper.MessageConsumer; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import java.io.IOException; import java.util.List; @@ -32,44 +25,40 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -@ExtendWith(SpringExtension.class) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class, RawEncodedJsonTopics.class}) -@EmbeddedKafka( - partitions = 1, - topics = { Asn1DecodedDataRouterApprovalTest.INPUT_TOPIC, Asn1DecodedDataRouterApprovalTest.OUTPUT_TOPIC_TX, Asn1DecodedDataRouterApprovalTest.OUTPUT_TOPIC_JSON }, - ports = 4242 -) +@Slf4j +@SpringBootTest(properties = { + "ode.kafka.topics.asn1.decoder-output=topic.Asn1DecoderOutputRouterApprovalTest", + "ode.kafka.topics.pojo.tx-map=topic.OdeMapTxPojoRouterApprovalTest", + "ode.kafka.topics.json.map=topic.OdeMapJsonRouterApprovalTest" +}) @DirtiesContext class Asn1DecodedDataRouterApprovalTest { - static final String INPUT_TOPIC = "topic.Asn1DecoderOutput"; - static final String OUTPUT_TOPIC_TX = "topic.OdeMapTxPojo"; - static final String OUTPUT_TOPIC_JSON = "topic.OdeMapJson"; + @Value("${ode.kafka.topics.asn1.decoder-output}") + private String decoderOutputTopic; - @Autowired - EmbeddedKafkaBroker embeddedKafka; + @Value("${ode.kafka.topics.pojo.tx-map}") + private String txMapTopic; - @Autowired - OdeKafkaProperties odeKafkaProperties; + @Value("${ode.kafka.topics.json.map}") + private String jsonMapTopic; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); @Test void testAsn1DecodedDataRouter() throws IOException { - List testCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); - - PojoTopics pojoTopics = new PojoTopics(); - pojoTopics.setTxMap(OUTPUT_TOPIC_TX); - - JsonTopics jsonTopics = new JsonTopics(); - jsonTopics.setMap(OUTPUT_TOPIC_JSON); - - Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeKafkaProperties, pojoTopics, jsonTopics); - - MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); + NewTopic inputTopic = new NewTopic(decoderOutputTopic, 1, (short) 1); + NewTopic outputTopicTx = new NewTopic(txMapTopic, 1, (short) 1); + NewTopic outputTopicJson = new NewTopic(jsonMapTopic, 1, (short) 1); + try { + embeddedKafka.addTopics(inputTopic, outputTopicTx, outputTopicJson); + } catch (RuntimeException e) { + // this usually happens when the topic already exists on the broker. We don't care if it already exists and + // add topic fails. we only care that the topics are created and we can run the tests. + log.warn("Exception while adding input topic", e); + } - asn1DecoderConsumer.setName("Asn1DecoderConsumer"); - decoderRouter.start(asn1DecoderConsumer, INPUT_TOPIC); + List testCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); @@ -79,28 +68,29 @@ void testAsn1DecodedDataRouter() throws IOException { DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); Consumer consumer = cf.createConsumer(); - embeddedKafka.consumeFromEmbeddedTopics(consumer, OUTPUT_TOPIC_TX, OUTPUT_TOPIC_JSON); + embeddedKafka.consumeFromEmbeddedTopics(consumer, txMapTopic, jsonMapTopic); for (ApprovalTestCase testCase : testCases) { - ProducerRecord producerRecord = new ProducerRecord<>(INPUT_TOPIC, 0, 0, testCase.getInput()); - producer.send(producerRecord); + ProducerRecord producerRecord = new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); + var sent = producer.send(producerRecord); + Awaitility.await().until(sent::isDone); - String received = KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_TX).value(); + String received = KafkaTestUtils.getSingleRecord(consumer, txMapTopic).value(); ObjectMapper mapper = new ObjectMapper(); OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), "Failed test case: " + testCase.getDescription()); // discard the JSON output - KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_JSON); + KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic); } List jsonTestCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json"); for (ApprovalTestCase testCase : jsonTestCases) { - ProducerRecord producerRecord = new ProducerRecord<>(INPUT_TOPIC, 0, 0, testCase.getInput()); + ProducerRecord producerRecord = new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); producer.send(producerRecord); - String received = KafkaTestUtils.getSingleRecord(consumer, OUTPUT_TOPIC_JSON).value(); + String received = KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic).value(); ObjectMapper mapper = new ObjectMapper(); OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java deleted file mode 100644 index 60519d012..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceControllerTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.services.asn1; - -import mockit.Expectations; -import mockit.Injectable; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import us.dot.its.jpo.ode.kafka.*; -import us.dot.its.jpo.ode.rsu.RsuProperties; -import us.dot.its.jpo.ode.security.SecurityServicesProperties; -import us.dot.its.jpo.ode.wrapper.MessageConsumer; - -import static org.junit.Assert.assertNotNull; - -class AsnCodecRouterServiceControllerTest { - - @Injectable - OdeKafkaProperties odeKafkaProperties; - @Injectable - JsonTopics jsonTopics; - @Injectable - PojoTopics pojoTopics; - @Injectable - Asn1CoderTopics asn1CoderTopics; - @Injectable - SDXDepositorTopics sdxDepositorTopics; - @Injectable - RsuProperties rsuProperties; - @Injectable - SecurityServicesProperties securityServicesProperties; - - @Test - @Disabled - void shouldStartTwoConsumers() { - - new Expectations() { - { - MessageConsumer.defaultStringMessageConsumer(anyString, anyString, (Asn1DecodedDataRouter) any); - times = 2; - } - }; - - assertNotNull(new AsnCodecRouterServiceController(odeKafkaProperties, jsonTopics, pojoTopics, asn1CoderTopics, sdxDepositorTopics, rsuProperties, securityServicesProperties)); - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index 253a64e06..485e96d67 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -1,29 +1,27 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeBsmMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputBSM"}, ports = 4242) class Asn1DecodeBSMJSONTest { private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -35,6 +33,15 @@ class Asn1DecodeBSMJSONTest { @Test void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } + Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java deleted file mode 100644 index 7e869ec04..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeMAPJSONTest.java +++ /dev/null @@ -1,112 +0,0 @@ -package us.dot.its.jpo.ode.services.asn1.message; - -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.json.JSONException; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.core.DefaultKafkaConsumerFactory; -import org.springframework.kafka.core.DefaultKafkaProducerFactory; -import org.springframework.kafka.test.EmbeddedKafkaBroker; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.kafka.test.utils.KafkaTestUtils; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; -import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeAsn1Payload; -import us.dot.its.jpo.ode.model.OdeMapMetadata; -import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; -import us.dot.its.jpo.ode.wrapper.MessageConsumer; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; - -@Slf4j -@ExtendWith(SpringExtension.class) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class, RawEncodedJsonTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {Asn1DecodeMAPJSONTest.INPUT_TOPIC, Asn1DecodeMAPJSONTest.OUTPUT_TOPIC}, ports = 4242) -class Asn1DecodeMAPJSONTest { - - static final String INPUT_TOPIC = "topic.OdeRawEncodedMAPJsonTEST"; - static final String OUTPUT_TOPIC = "topic.Asn1DecoderInputMAPTEST"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Autowired - RawEncodedJsonTopics rawEncodedJsonTopics; - - @Autowired - private EmbeddedKafkaBroker embeddedKafka; - - @Test - void testProcess() throws JSONException { - Asn1DecodeMAPJSON testDecodeMapJson = new Asn1DecodeMAPJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - String json = "{\"metadata\":{\"recordType\":\"mapTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"b91c5c0f-1c42-457e-b7c5-54505c942667\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:04:47.440601200Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"mapSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B10012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C900008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - OdeAsn1Data resultOdeObj = testDecodeMapJson.process(json); - - // Validate the metadata - OdeMapMetadata jsonMetadataObj = (OdeMapMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeMapMetadata.MapSource.RSU, jsonMetadataObj.getMapSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"0012839338023000205E96094D40DF4C2CA626C8516E02DC3C2010640000000289E01C009F603F42E88039900000000A41107B027D80FD0A4200C6400000002973021C09F603DE0C16029200000080002A8A008D027D98FEE805404FB0E1085F60588200028096021200000080002AA0007D027D98FE9802E04FB1200C214456228000A02B1240005022C03240000020000D56B40BC04FB35FF655E2C09F623FB81C835FEC0DB240A0A2BFF4AEBF82C660000804B0089000000800025670034013ECD7FB9578E027D9AFF883C4E050515FFA567A41635000040258024800000400012B8F81F409F663FAC094013ECD7FC83DDB02829AFFA480BC04FB02C6E0000804B09C5000000200035EA98A9604F60DA6C7C113D505C35FFE941D409F65C05034C050500C9880004409BC800000006D2BD3CEC813C40CDE062C1FD400000200008791EA3DB3CF380A009F666F05005813D80FFE0A0588C00040092106A00000000BC75CAC009F66DB54C04A813D80A100801241ED40000000078EBAE3B6DA7A008809E2050904008811F100000000BC72389009F60ECA8002049C400000002F1B2CA3027D93A71FA813EC204BC400000002F1B2B34027B0397608880CD10000000039B8E1A51036820505080D51000000003A7461ED1036760505080DD1000000003B2F62311006260505160BCA00000080002B785E2A80A0A6C028DE728145037F1F9E456488000202B2540001022C1894000001000057058C5B81414D806DBCD4028A18F4DF23A050502C8D0000404B05A5000000800035B6471BC05053602431F380A2864087BDB0141458064AB0D6C00053FC013EC0B0680006012C15940000020000D6C06C6581414D807FB972028A1901D78DC050536020EC1800A0A6C039D639813D80B0780006012C1494000002000096AB8C6581414D8062BE32028A1B01417E04050A360172D77009E2058440003009409C200000040006B3486A480A0A1CAB7134C8117DCC02879B018FAE2C050F3601CED54809E21012720000000067FBAD0007E7E84045C80000000100661580958004041C8000000019F3658401CDFA2C0D64000002000144016C02C36DDFFF0282984ACC1EE05052C36F0AC02828669D82DA8F821480A0A10F140002C8E0001004B03190000008000519FD190C43B2E0066108B08401428C342A0CE02828258A0604A6BE959AEE0E6050502C920001004B02D90000008000459FA164404FB30A8580A00A14619C306701414C32CE10E02829659081F814141029030164B0000802E8000802000035FDB1D84C09EC6C003BA14814140B0540003012C187400040080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C90000800\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); - } - - @Test - void testProcess_ApprovalTest() throws IOException { - String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; - List approvalTestCases = deserializeTestCases(path); - - Asn1DecodeMAPJSON asn1DecodeMAPSON = new Asn1DecodeMAPJSON(odeKafkaProperties, OUTPUT_TOPIC); - MessageConsumer asn1RawMAPJSONConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), asn1DecodeMAPSON); - asn1RawMAPJSONConsumer.setName("asn1DecodeMAPJSONTest"); - asn1DecodeMAPSON.start(asn1RawMAPJSONConsumer, INPUT_TOPIC); - - Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); - DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); - Producer producer = producerFactory.createProducer(); - - Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); - DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); - Consumer testConsumer = cf.createConsumer(); - embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, OUTPUT_TOPIC); - - for (ApprovalTestCase approvalTestCase : approvalTestCases) { - // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer - ProducerRecord r = new ProducerRecord<>(INPUT_TOPIC, approvalTestCase.getInput()); - producer.send(r); - - ConsumerRecord actualRecord = KafkaTestUtils.getSingleRecord(testConsumer, OUTPUT_TOPIC); - assertEquals(approvalTestCase.getExpected(), actualRecord.value(), approvalTestCase.getDescription()); - } - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index aa2f7bb16..6d310bb62 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -1,29 +1,27 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputPSM"}, ports = 4242) class Asn1DecodePSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -33,9 +31,16 @@ class Asn1DecodePSMJSONTest { @Autowired Asn1CoderTopics asn1CoderTopics; - @Test void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index 9bc336bf4..a2530c228 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -1,29 +1,27 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSpatMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSPAT"}, ports = 4242) class Asn1DecodeSPATJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -35,7 +33,16 @@ class Asn1DecodeSPATJSONTest { @Test void testProcess() throws JSONException { - Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } + + Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput() ); OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index d9ccc1962..e50f73d8b 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -1,29 +1,27 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSrmMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSRM"}, ports = 4242) class Asn1DecodeSRMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -35,6 +33,15 @@ class Asn1DecodeSRMJSONTest { @Test void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } + Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index 208cc0804..d0609c35b 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -1,29 +1,27 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSsmMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputSSM"}, ports = 4242) class Asn1DecodeSSMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -35,6 +33,15 @@ class Asn1DecodeSSMJSONTest { @Test void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } + Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index 272b6d34d..c1380f751 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -1,30 +1,28 @@ package us.dot.its.jpo.ode.services.asn1.message; +import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.kafka.test.context.EmbeddedKafka; -import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.model.Asn1Encoding.EncodingRule; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimMetadata; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) -@DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.Asn1DecoderInputTIM"}, ports = 4242) class Asn1DecodeTIMJSONTest { private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; @@ -36,6 +34,15 @@ class Asn1DecodeTIMJSONTest { @Test void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic + } + Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java deleted file mode 100644 index 7aec1623d..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/AsnCodecMessageServiceControllerTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package us.dot.its.jpo.ode.services.asn1.message; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; - -import static org.junit.Assert.assertNotNull; - -@ExtendWith(SpringExtension.class) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = {OdeKafkaProperties.class, RawEncodedJsonTopics.class, Asn1CoderTopics.class}) -class AsnCodecMessageServiceControllerTest { - - @Autowired - OdeKafkaProperties odeKafkaProps; - - @Autowired - RawEncodedJsonTopics rawEncodedJsonTopics; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void shouldStartTwoConsumers() { - AsnCodecMessageServiceController asnCodecMessageServiceController = new AsnCodecMessageServiceController(odeKafkaProps, rawEncodedJsonTopics, asn1CoderTopics); - assertNotNull(asnCodecMessageServiceController); - } - -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java index 58b4ab4c5..68564da35 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/json/ToJsonServiceControllerTest.java @@ -19,9 +19,9 @@ import mockit.Expectations; import mockit.Injectable; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.wrapper.MessageConsumer; import us.dot.its.jpo.ode.wrapper.MessageProcessor; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java new file mode 100644 index 000000000..e7b4330aa --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.testUtilities; + +import org.springframework.kafka.KafkaException; +import org.springframework.kafka.test.EmbeddedKafkaBroker; + +public final class EmbeddedKafkaHolder { + + private static final EmbeddedKafkaBroker embeddedKafka = new EmbeddedKafkaBroker(1, true, 1) + .brokerListProperty("spring.kafka.bootstrap-servers"); + + private static boolean started; + + public static EmbeddedKafkaBroker getEmbeddedKafka() { + if (!started) { + try { + embeddedKafka.kafkaPorts(4242); + embeddedKafka.afterPropertiesSet(); + } + catch (Exception e) { + throw new KafkaException("Embedded broker failed to start", e); + } + started = true; + } + return embeddedKafka; + } + + private EmbeddedKafkaHolder() { + super(); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 5557dcd31..8911c5bcf 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -27,10 +27,10 @@ import mockit.Expectations; import mockit.Injectable; import mockit.Tested; -import us.dot.its.jpo.ode.kafka.Asn1CoderTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData; diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java index 2d6ecf6eb..443b0fdfb 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimIngestTrackerPropertiesTest.java @@ -25,6 +25,6 @@ void isTrackingEnabled() { @Test void getMonitoringInterval() { - assertEquals(1, timIngestTrackerProperties.getInterval()); + assertEquals(10, timIngestTrackerProperties.getInterval()); } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java index 7790fbee7..3c14a6a60 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java @@ -1,35 +1,24 @@ package us.dot.its.jpo.ode.udp.map; import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.json.JSONObject; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.test.EmbeddedKafkaBroker; -import org.springframework.kafka.test.context.EmbeddedKafka; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit.jupiter.SpringExtension; -import org.springframework.test.context.junit4.SpringRunner; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; +import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; +import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; import us.dot.its.jpo.ode.testUtilities.TestUDPClient; -import us.dot.its.jpo.ode.udp.controller.ServiceManager; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -import us.dot.its.jpo.ode.udp.controller.UdpServiceThreadFactory; import us.dot.its.jpo.ode.util.DateTimeUtils; -import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; import java.io.IOException; import java.time.Clock; @@ -42,37 +31,24 @@ import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; @Slf4j -@ExtendWith(SpringExtension.class) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) -@EnableConfigurationProperties(value = {UDPReceiverProperties.class, OdeKafkaProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class}) -@RunWith(SpringRunner.class) +@SpringBootTest(properties = {"ode.kafka.topics.raw-encoded-json.map=topic.MapReceiverTestMAPJSON", "ode.receivers.map.receiver-port=12412"}) @DirtiesContext -@EmbeddedKafka(partitions = 1, topics = {"topic.OdeRawEncodedMAPJson"}, ports = 4242) class MapReceiverTest { + private final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); @Autowired UDPReceiverProperties udpReceiverProperties; - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - RawEncodedJsonTopics rawEncodedJsonTopics; + @Value(value = "${ode.kafka.topics.raw-encoded-json.map}") + private String rawJsonMapTopic; - @Autowired - private EmbeddedKafkaBroker embeddedKafka; + @Value(value = "${ode.receivers.map.receiver-port}") + private int mapReceiverPort; - ServiceManager rm; - TestUDPClient udpClient; - MapReceiver mapReceiver; - - @BeforeEach - public void setUp() { - rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); - - mapReceiver = new MapReceiver(udpReceiverProperties.getMap(), - odeKafkaProperties, - rawEncodedJsonTopics.getMap()); + @Test + void testMapReceiver() throws IOException { + String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json"; + List approvalTestCases = deserializeTestCases(path, "\u0000\u0012"); // Set the clock to a fixed time so that the MapReceiver will produce the same output every time DateTimeUtils.setClock(Clock.fixed(Instant.parse("2020-01-01T00:00:00Z"), Clock.systemUTC().getZone())); @@ -81,37 +57,33 @@ public void setUp() { // and the schema version is set to the static schema version in the constructor. This means that the schema version // will be set to 6 for all OdeMsgMetadata objects created in the MapReceiver run method's code path. OdeMsgMetadata.setStaticSchemaVersion(7); - } - - @AfterEach - public void tearDown() { - mapReceiver.setStopped(true); - udpClient.close(); - } - @Test - void testMapReceiver() throws IOException { - String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json"; - List approvalTestCases = deserializeTestCases(path, "\u0000\u0012"); - - // Start the MapReceiver in a new thread - rm.submit(mapReceiver); + try { + embeddedKafka.addTopics(new NewTopic(rawJsonMapTopic, 1, (short) 1)); + } catch (Exception e) { + log.warn("Couldn't create topics. If the error indicates the topics already exist, this message is safe to ignore: {}", e.getMessage()); + } // Set up a Kafka consumer - Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); + Map consumerProps = KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka); DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); Consumer consumer = cf.createConsumer(); - embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getMap()); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawJsonMapTopic); - udpClient = new TestUDPClient(udpReceiverProperties.getMap().getReceiverPort()); + // Clarifying note (for Spring newbies): + // UdpServicesController is annotated with @Controller, and this test class is annotated with @SpringBootTest + // so a UdpServicesController will be instantiated before this test runs. That means the MapReceiver will also + // be instantiated and ready to consume UDP traffic from the same port we configure the TestUDPClient to send packets to. + TestUDPClient udpClient = new TestUDPClient(mapReceiverPort); for (ApprovalTestCase approvalTestCase : approvalTestCases) { udpClient.send(approvalTestCase.getInput()); - ConsumerRecord produced = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getMap()); + ConsumerRecord produced = KafkaTestUtils.getSingleRecord(consumer, rawJsonMapTopic); JSONObject producedJson = new JSONObject(produced.value()); JSONObject expectedJson = new JSONObject(approvalTestCase.getExpected()); + // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), producedJson.getJSONObject("metadata").get("serialId")); expectedJson.getJSONObject("metadata").remove("serialId"); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java index 29a31b3eb..c24d08a35 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/upload/FileUploadControllerTest.java @@ -26,10 +26,10 @@ import org.springframework.web.multipart.MultipartFile; import us.dot.its.jpo.ode.coder.stream.FileImporterProperties; import us.dot.its.jpo.ode.importer.ImporterDirectoryWatcher; -import us.dot.its.jpo.ode.kafka.FileTopics; -import us.dot.its.jpo.ode.kafka.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.FileTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.storage.StorageFileNotFoundException; import us.dot.its.jpo.ode.storage.StorageService; diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml index 90d61d6a8..9e9304c61 100644 --- a/jpo-ode-svcs/src/test/resources/application.yaml +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -3,20 +3,18 @@ spring: multipart: max-file-size: 1MB max-request-size: 1MB - embedded: - kafka: - brokers: - property: localhost:9092 kafka: - bootstrap-servers: localhost:9092 + bootstrap-servers: localhost:4242 producer: key-serializer: org.apache.kafka.common.serialization.StringSerializer value-serializer: org.apache.kafka.common.serialization.StringSerializer + client-id: "ode-svcs-producer" consumer: key-deserializer: org.apache.kafka.common.serialization.StringDeserializer value-deserializer: org.apache.kafka.common.serialization.StringDeserializer group-id: test-group auto-offset-reset: earliest + client-id: "ode-svcs-consumer" ode: output-schema-version: 7 security-services: @@ -131,4 +129,4 @@ ode: obu-log-upload-location: "bsmlog" tim-ingest-monitoring: tracking-enabled: true - interval: 1 \ No newline at end of file + interval: 10 \ No newline at end of file From d6a038d38bd00bbf1b20bf8fd1de52a8d42efdc5 Mon Sep 17 00:00:00 2001 From: John-Wiens Date: Tue, 26 Nov 2024 15:04:55 -0700 Subject: [PATCH 071/264] Switching adopt builder to temurin --- .github/workflows/artifact-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/artifact-publish.yml b/.github/workflows/artifact-publish.yml index 8321ef7e0..03700878f 100644 --- a/.github/workflows/artifact-publish.yml +++ b/.github/workflows/artifact-publish.yml @@ -17,7 +17,7 @@ jobs: uses: actions/setup-java@v4 with: java-version: '21' - distribution: 'adopt' + distribution: 'temurin' - name: Remove snapshot from version run: mvn versions:set -DremoveSnapshot From 7c5f91a8af0f70424f73134ade1d1682964dd833 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 07:41:25 -0700 Subject: [PATCH 072/264] Cleaned up a TimTransmogrifier test by extracting some helper methods --- .../ode/traveler/TimTransmogrifierTest.java | 86 +++++++++++++------ 1 file changed, 60 insertions(+), 26 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index af719d9ab..e9ac6268e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -265,37 +265,17 @@ void testConvertToXMLMessageFrame() void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { // prepare String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); - OdeTravelerInputData odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); - ServiceRequest request = odeTID.getRequest(); - request.setOde(new ServiceRequest.OdeInternal()); - request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); - OdeTravelerInformationMessage tim = odeTID.getTim(); - OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); - OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); - timMetadata.setOdePacketID(tim.getPacketID()); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); - latestStartDateTime = latestStartDateTime == null || latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime; - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); - SerialId serialId = new SerialId(); - serialId.setStreamId("testStreamId"); - timMetadata.setSerialId(serialId); - timMetadata.setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.TMC); - timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + + SerialId serialId = prepareSerialId(); + OdeTravelerInputData odeTID = prepareOdeTID(timRequestContainingCircleGeometry); + OdeRequestMsgMetadata timMetadata = prepareMetadata(odeTID, serialId); + ObjectNode encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - timMetadata.setSchemaVersion(7); // Set the clock to a fixed instant for value comparison DateTimeUtils.setClock(Clock.fixed(Instant.parse("2024-11-05T16:51:14.473Z"), ZoneId.of("UTC"))); - + // execute String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); @@ -326,4 +306,58 @@ void testConstructorIsPrivate() throws NoSuchMethodException { assertThrows(InvocationTargetException.class, constructor::newInstance); } + /** + * Helper method to prepare a SerialId object for testing + * @return a SerialId object + */ + private SerialId prepareSerialId() { + SerialId serialId = new SerialId(); + serialId.setStreamId("testStreamId"); + return serialId; + } + + /** + * Helper method to prepare an OdeTravelerInputData object for testing + * @param timRequestContainingCircleGeometry a JSON string containing a TIM request with a circle geometry + * @return an OdeTravelerInputData object + * @throws JsonUtilsException if there is an issue parsing the JSON string + */ + private OdeTravelerInputData prepareOdeTID(String timRequestContainingCircleGeometry) throws JsonUtilsException { + return (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); + } + + /** + * Helper method to prepare an OdeRequestMsgMetadata object for testing + * @param odeTID an OdeTravelerInputData object + * @param serialId a SerialId object + * @return an OdeRequestMsgMetadata object + * @throws ParseException if there is an issue parsing the date + */ + private OdeRequestMsgMetadata prepareMetadata(OdeTravelerInputData odeTID, SerialId serialId) throws ParseException { + ServiceRequest request = odeTID.getRequest(); + request.setOde(new ServiceRequest.OdeInternal()); + request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + timMetadata.setOdePacketID(tim.getPacketID()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); + latestStartDateTime = latestStartDateTime == null || latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime; + } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + + timMetadata.setSerialId(serialId); + timMetadata.setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.TMC); + timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + timMetadata.setSchemaVersion(7); + return timMetadata; + } + } From 931789563a438b3cf2e83c001ef60a14a507ad91 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 07:41:39 -0700 Subject: [PATCH 073/264] Updated expected output for a TimTransmogrifier test to comply with J2735 2024 --- .../its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml index d9de3debd..cbaa4ab30 100644 --- a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml @@ -1 +1 @@ -us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPERMessageFrame3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000

411535930-104655785018240
50004868null \ No newline at end of file +us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPERMessageFrame3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000
411535930-104655785018240
50
004868null
\ No newline at end of file From e05405fca023c92f3c353c4d02275ebe3a3e8b66 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 10:47:13 -0700 Subject: [PATCH 074/264] Updated TIM schema to comply with J2735 2024 --- .../src/main/resources/schemas/schema-tim.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index 14ccfb46e..a0fb1aaaf 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -416,7 +416,7 @@ "J2735TravelerDataFrame": { "type": "object", "properties": { - "notUsed": { + "doNotUse1": { "type": "string" }, "frameType": { @@ -452,7 +452,7 @@ "priority": { "type": "string" }, - "notUsed1": { + "doNotUse2": { "type": "string" }, "regions": { @@ -470,10 +470,10 @@ } ] }, - "notUsed2": { + "doNotUse3": { "type": "string" }, - "notUsed3": { + "doNotUse4": { "type": "string" }, "content": { @@ -484,16 +484,16 @@ } }, "required": [ - "notUsed", + "doNotUse1", "frameType", "msgId", "startTime", "durationTime", "priority", - "notUsed1", + "doNotUse2", "regions", - "notUsed2", - "notUsed3", + "doNotUse3", + "doNotUse4", "content" ] }, From 796e5cebe4108da3dda2311b8136196668700363 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 10:48:10 -0700 Subject: [PATCH 075/264] Updated data files to comply with J2735 2024 --- .../TIM_BroadcastSampleOutput.json | 48 +- .../archive/TimTestGeometry.json | 4 +- .../archive/TimTestPath_LL.json | 4 +- .../archive/TimTestPath_XY.json | 4 +- .../archive/TimTestoldRegion.json | 4 +- .../archive/testExitService.json | 4 +- .../tim_geometry_multi_rsu_no_sdw.json | 4 +- .../tim_geometry_multi_rsu_sdw.json | 4 +- ...tim_path_xy_node_any_multi_rsu_no_sdw.json | 4 +- ..._path_xy_node_latlon_multi_rsu_no_sdw.json | 4 +- .../tim_path_xy_node_latlon_no_rsu_sdw.json | 4 +- .../deprecated/tim_region_multiRSU.json | 4 +- .../deprecated/tim_region_singleRSU.json | 4 +- .../tim_region_singleRSU_hexCRC.json | 4 +- .../tim_path_LL_single_rsu_no_sdw.json | 4 +- .../tim_path_multiRSU_hexCRC.json | 4 +- .../tim_path_singleRSU.json | 4 +- ...im_path_xy_node_any_single_rsu_no_sdw.json | 4 +- data/dnMsg.json | 2 +- data/rxMsg_TIM_Asn1DecoderOutput.xml | 8 +- data/rxMsg_TIM_GeneratedBy_RSU.json | 486 +++++++++--------- data/rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.json | 332 ++++++------ .../src/test/resources/sdwRequest.json | 4 +- 23 files changed, 474 insertions(+), 474 deletions(-) diff --git a/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json b/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json index 8357f788c..745b6473b 100644 --- a/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json +++ b/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json @@ -1,24 +1,24 @@ -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":29,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":29},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:39.058Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"DE9AAC79"},"requestID":"DE9AAC79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":29,"recordId":0,"serialNumber":29},"odeReceivedAt":"2019-03-12T19:50:39.057Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"notUsed1":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":28,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":28},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:38.120Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":19595894},"requestID":19595894,"groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":28,"recordId":0,"serialNumber":28},"odeReceivedAt":"2019-03-12T19:50:38.118Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"notUsed1":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":27,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":27},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:37.242Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"C7062151"},"requestID":"C7062151","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":27,"recordId":0,"serialNumber":27},"odeReceivedAt":"2019-03-12T19:50:37.240Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"notUsed1":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":26,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":26},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:36.350Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411139330,"long":-1048507720}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":155120}},"msgCnt":1}}}}}}},"startTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"stopTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"distType":"02","asdmType":2,"asdmID":"C064E753"},"requestID":"C064E753","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":26,"recordId":0,"serialNumber":26},"odeReceivedAt":"2019-03-12T19:50:36.348Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.113933,"longitude":-104.850772},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-04-18T11:20-06:00","durationTime":2000,"priority":5,"notUsed1":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":25,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":25},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:35.499Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":25,"recordId":0,"serialNumber":25},"odeReceivedAt":"2019-03-12T19:50:35.497Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"notUsed1":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":24,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":24},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:34.670Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":24,"recordId":0,"serialNumber":24},"odeReceivedAt":"2019-03-12T19:50:34.666Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"notUsed1":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":23,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":23},"sanitized":false,"recordGeneratedAt":"2018-06-11T16:00:00Z","odeReceivedAt":"2019-03-12T19:50:33.824Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":232800,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-XY1":{"x":-512,"y":511}}},{"delta":{"node-XY2":{"x":-1024,"y":1023}}},{"delta":{"node-XY3":{"x":-2048,"y":2047}}},{"delta":{"node-XY4":{"x":-4096,"y":4095}}},{"delta":{"node-XY5":{"x":-8192,"y":8191}}},{"delta":{"node-XY6":{"x":-32768,"y":32767}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":23,"recordId":0,"serialNumber":23},"odeReceivedAt":"2019-03-12T19:50:33.823Z","schemaVersion":6,"recordGeneratedAt":"2018-06-11T16:00:00Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-06-11T16:00:00.000Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"notUsed1":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-XY","x":-5.12,"y":5.11},{"delta":"node-XY","x":-10.24,"y":10.23},{"delta":"node-XY","x":-20.48,"y":20.47},{"delta":"node-XY","x":-40.96,"y":40.95},{"delta":"node-XY","x":-81.92,"y":81.91},{"delta":"node-XY","x":-327.68,"y":327.67},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":22,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":22},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:32.883Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"B5DF2B65"},"requestID":"B5DF2B65","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":22,"recordId":0,"serialNumber":22},"odeReceivedAt":"2019-03-12T19:50:32.879Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"notUsed1":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":21,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":21},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:31.737Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"62048F79"},"requestID":"62048F79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":21,"recordId":0,"serialNumber":21},"odeReceivedAt":"2019-03-12T19:50:31.733Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"notUsed1":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":20,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":20},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:30.318Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":30982,"lat":14562}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":20,"recordId":0,"serialNumber":20},"odeReceivedAt":"2019-03-12T19:50:30.317Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"notUsed1":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":19,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":19},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:28.990Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"6D596E08"},"requestID":"6D596E08","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":19,"recordId":0,"serialNumber":19},"odeReceivedAt":"2019-03-12T19:50:28.988Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"notUsed1":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} -{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":18,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":18},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:26.827Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"notUsed2":0,"notUsed3":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":18,"recordId":0,"serialNumber":18},"odeReceivedAt":"2019-03-12T19:50:26.823Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"notUsed":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"notUsed1":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":29,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":29},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:39.058Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"DE9AAC79"},"requestID":"DE9AAC79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":29,"recordId":0,"serialNumber":29},"odeReceivedAt":"2019-03-12T19:50:39.057Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":28,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":28},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:38.120Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":19595894},"requestID":19595894,"groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":28,"recordId":0,"serialNumber":28},"odeReceivedAt":"2019-03-12T19:50:38.118Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":27,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":27},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:37.242Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"C7062151"},"requestID":"C7062151","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":27,"recordId":0,"serialNumber":27},"odeReceivedAt":"2019-03-12T19:50:37.240Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":26,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":26},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:36.350Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411139330,"long":-1048507720}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":155120}},"msgCnt":1}}}}}}},"startTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"stopTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"distType":"02","asdmType":2,"asdmID":"C064E753"},"requestID":"C064E753","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":26,"recordId":0,"serialNumber":26},"odeReceivedAt":"2019-03-12T19:50:36.348Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.113933,"longitude":-104.850772},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-04-18T11:20-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":25,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":25},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:35.499Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":25,"recordId":0,"serialNumber":25},"odeReceivedAt":"2019-03-12T19:50:35.497Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":24,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":24},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:34.670Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":24,"recordId":0,"serialNumber":24},"odeReceivedAt":"2019-03-12T19:50:34.666Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":23,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":23},"sanitized":false,"recordGeneratedAt":"2018-06-11T16:00:00Z","odeReceivedAt":"2019-03-12T19:50:33.824Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":232800,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-XY1":{"x":-512,"y":511}}},{"delta":{"node-XY2":{"x":-1024,"y":1023}}},{"delta":{"node-XY3":{"x":-2048,"y":2047}}},{"delta":{"node-XY4":{"x":-4096,"y":4095}}},{"delta":{"node-XY5":{"x":-8192,"y":8191}}},{"delta":{"node-XY6":{"x":-32768,"y":32767}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":23,"recordId":0,"serialNumber":23},"odeReceivedAt":"2019-03-12T19:50:33.823Z","schemaVersion":6,"recordGeneratedAt":"2018-06-11T16:00:00Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-06-11T16:00:00.000Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-XY","x":-5.12,"y":5.11},{"delta":"node-XY","x":-10.24,"y":10.23},{"delta":"node-XY","x":-20.48,"y":20.47},{"delta":"node-XY","x":-40.96,"y":40.95},{"delta":"node-XY","x":-81.92,"y":81.91},{"delta":"node-XY","x":-327.68,"y":327.67},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":22,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":22},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:32.883Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"B5DF2B65"},"requestID":"B5DF2B65","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":22,"recordId":0,"serialNumber":22},"odeReceivedAt":"2019-03-12T19:50:32.879Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":21,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":21},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:31.737Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"62048F79"},"requestID":"62048F79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":21,"recordId":0,"serialNumber":21},"odeReceivedAt":"2019-03-12T19:50:31.733Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":20,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":20},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:30.318Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":30982,"lat":14562}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":20,"recordId":0,"serialNumber":20},"odeReceivedAt":"2019-03-12T19:50:30.317Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":19,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":19},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:28.990Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"6D596E08"},"requestID":"6D596E08","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":19,"recordId":0,"serialNumber":19},"odeReceivedAt":"2019-03-12T19:50:28.988Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":18,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":18},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:26.827Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}},"dataType":"TravelerInformation"}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":18,"recordId":0,"serialNumber":18},"odeReceivedAt":"2019-03-12T19:50:26.823Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} diff --git a/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json b/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json index 3715926e0..eac68adb6 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json @@ -9,7 +9,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "0", "msgID": "RoadSignID", "position": { @@ -23,7 +23,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json b/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json index 4f41c40bb..a7f08dd2d 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json @@ -9,7 +9,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "0", "msgID": "RoadSignID", "position": { @@ -23,7 +23,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "835", "priority": "2", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "SpeedLimit", diff --git a/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json b/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json index ee685dd3d..493529b04 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json @@ -9,7 +9,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "1", "msgID": "RoadSignID", "position": { @@ -23,7 +23,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "835", "priority": "2", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "SpeedLimit", diff --git a/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json b/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json index 8062d1282..0f33b4ea1 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json @@ -9,7 +9,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "1", "msgID": "RoadSignID", "position": { @@ -23,7 +23,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "835", "priority": "2", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "SpeedLimit", diff --git a/data/TIM_Message_Testing_Files/archive/testExitService.json b/data/TIM_Message_Testing_Files/archive/testExitService.json index e5af801b7..7848d2dbe 100644 --- a/data/TIM_Message_Testing_Files/archive/testExitService.json +++ b/data/TIM_Message_Testing_Files/archive/testExitService.json @@ -289,8 +289,8 @@ ] }, "content": { - "notUsed2": "0", - "notUsed3": "0", + "doNotUse3": "0", + "doNotUse4": "0", "contentType": { "advisory": [], "workZone": [], diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json index 6991b95a8..744759cca 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json @@ -45,7 +45,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -62,7 +62,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json index 5453c67ab..5fc554b58 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json @@ -58,7 +58,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -75,7 +75,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json index 376e98934..9241df8c0 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json @@ -48,7 +48,7 @@ "startDateTime": "2018-06-11T10:00-06:00", "durationTime": 2000, "frameType": "advisory", - "notUsed": "0", + "doNotUse1": "0", "msgId": { "roadSignID": { "mutcdCode": "warning", @@ -60,7 +60,7 @@ } }, "priority": "5", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "southbound_Timberline_20_30_RSU-192.168.0.100", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json index b679ac975..2f4952e9f 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json @@ -48,7 +48,7 @@ "startDateTime": "2018-06-11T10:00-06:00", "durationTime": 2000, "frameType": "advisory", - "notUsed": "0", + "doNotUse1": "0", "msgId": { "roadSignID": { "mutcdCode": "warning", @@ -60,7 +60,7 @@ } }, "priority": "5", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "southbound_Timberline_20_30_RSU-192.168.0.100", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json index 166ca9318..069ee9367 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json @@ -24,7 +24,7 @@ "startDateTime": "2018-04-18T11:20-06:00", "durationTime": 2000, "frameType": "advisory", - "notUsed": "0", + "doNotUse1": "0", "msgId": { "roadSignID": { "mutcdCode": "warning", @@ -36,7 +36,7 @@ } }, "priority": "5", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "southbound_Timberline_20_30_RSU-192.168.0.100", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json index 14d1c89c4..745445cac 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json @@ -58,7 +58,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -75,7 +75,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json index 9311d8587..43c7a926b 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json @@ -42,7 +42,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -59,7 +59,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json index 024920dc4..f1045163e 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json @@ -42,7 +42,7 @@ "urlB": "null", "dataframes": [ { - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -59,7 +59,7 @@ "startDateTime": "2017-12-01T17:47:11-05:00", "durationTime": "22", "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "bob", diff --git a/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json index e717473c0..ed074cb2b 100644 --- a/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json @@ -47,7 +47,7 @@ { "startDateTime": "2017-08-02T22:25:00.000Z", "durationTime": 1, - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -62,7 +62,7 @@ } }, "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "Testing TIM", diff --git a/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json b/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json index fca9e6364..30c02513e 100644 --- a/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json +++ b/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json @@ -60,7 +60,7 @@ { "startDateTime": "2017-08-02T22:25:00.000Z", "durationTime": 1, - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -75,7 +75,7 @@ } }, "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "Testing TIM", diff --git a/data/TIM_Message_Testing_Files/tim_path_singleRSU.json b/data/TIM_Message_Testing_Files/tim_path_singleRSU.json index be1f0ca8b..0d22102d5 100644 --- a/data/TIM_Message_Testing_Files/tim_path_singleRSU.json +++ b/data/TIM_Message_Testing_Files/tim_path_singleRSU.json @@ -44,7 +44,7 @@ { "startDateTime": "2017-08-02T22:25:00.000Z", "durationTime": 1, - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -59,7 +59,7 @@ } }, "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "Testing TIM", diff --git a/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json index 1c8e939b0..e255ea9e2 100644 --- a/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json @@ -31,7 +31,7 @@ { "startDateTime": "2017-08-02T22:25:00.000Z", "durationTime": 1, - "notUsed": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -46,7 +46,7 @@ } }, "priority": "0", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "Testing TIM", diff --git a/data/dnMsg.json b/data/dnMsg.json index 5719c38e1..6ff36591a 100644 --- a/data/dnMsg.json +++ b/data/dnMsg.json @@ -1 +1 @@ -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"OBU","receivedMessageDetails":{"locationData":{"elevation":1372.4,"heading":297.3,"latitude":40.5655211,"speed":0.46,"longitude":-105.0323263},"rxSource":"NA"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":14742,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":1,"bundleId":73},"sanitized":false,"recordGeneratedAt":"2018-05-02T16:47:45.603Z","recordType":"dnMsg","logFileName":"dnMsg.gz","odeReceivedAt":"2019-04-09T18:08:17.818Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":174827,"packetID":"D3BAFF020000000000","dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"anchor":{"elevation":14742,"lat":405662581,"long":-1050326099},"laneWidth":400,"directionality":{"forward":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050329714,"lat":405662567}}},{"delta":{"node-LatLon":{"lon":-1050335237,"lat":405662769}}},{"delta":{"node-LatLon":{"lon":-1050335993,"lat":405663179}}},{"delta":{"node-LatLon":{"lon":-1050336397,"lat":405664057}}},{"delta":{"node-LatLon":{"lon":-1050336440,"lat":405667220}}},{"delta":{"node-LatLon":{"lon":-1050336660,"lat":405671451}}},{"delta":{"node-LatLon":{"lon":-1050336938,"lat":405672504}}},{"delta":{"node-LatLon":{"lon":-1050337672,"lat":405672940}}}]}}}}},"direction":1111111111111111}},"durationTime":2880,"notUsed2":0,"notUsed3":0,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"msgId":{"furtherInfoID":"0214"},"startTime":174826,"priority":7,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":532}},{"item":{"itis":531}},{"item":{"text":"User Initiated Distress"}},{"item":{"text":"Vehicle-Class: Unknown"}}]}}}},"msgCnt":51}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"OBU","receivedMessageDetails":{"locationData":{"elevation":1372.4,"heading":297.3,"latitude":40.5655211,"speed":0.46,"longitude":-105.0323263},"rxSource":"NA"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":14742,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":1,"bundleId":73},"sanitized":false,"recordGeneratedAt":"2018-05-02T16:47:45.603Z","recordType":"dnMsg","logFileName":"dnMsg.gz","odeReceivedAt":"2019-04-09T18:08:17.818Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":174827,"packetID":"D3BAFF020000000000","dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"anchor":{"elevation":14742,"lat":405662581,"long":-1050326099},"laneWidth":400,"directionality":{"forward":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050329714,"lat":405662567}}},{"delta":{"node-LatLon":{"lon":-1050335237,"lat":405662769}}},{"delta":{"node-LatLon":{"lon":-1050335993,"lat":405663179}}},{"delta":{"node-LatLon":{"lon":-1050336397,"lat":405664057}}},{"delta":{"node-LatLon":{"lon":-1050336440,"lat":405667220}}},{"delta":{"node-LatLon":{"lon":-1050336660,"lat":405671451}}},{"delta":{"node-LatLon":{"lon":-1050336938,"lat":405672504}}},{"delta":{"node-LatLon":{"lon":-1050337672,"lat":405672940}}}]}}}}},"direction":1111111111111111}},"durationTime":2880,"doNotUse3":0,"doNotUse4":0,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"msgId":{"furtherInfoID":"0214"},"startTime":174826,"priority":7,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":532}},{"item":{"itis":531}},{"item":{"text":"User Initiated Distress"}},{"item":{"text":"Vehicle-Class: Unknown"}}]}}}},"msgCnt":51}}}},"dataType":"TravelerInformation"}} diff --git a/data/rxMsg_TIM_Asn1DecoderOutput.xml b/data/rxMsg_TIM_Asn1DecoderOutput.xml index a1eec0eb3..14c7d46a2 100644 --- a/data/rxMsg_TIM_Asn1DecoderOutput.xml +++ b/data/rxMsg_TIM_Asn1DecoderOutput.xml @@ -51,7 +51,7 @@ 00000000003616371F - 0 + 0 @@ -72,7 +72,7 @@ 359511 10080 6 - 0 + 0 @@ -116,8 +116,8 @@ - 0 - 0 + 0 + 0 diff --git a/data/rxMsg_TIM_GeneratedBy_RSU.json b/data/rxMsg_TIM_GeneratedBy_RSU.json index 623b84716..0a1e68768 100644 --- a/data/rxMsg_TIM_GeneratedBy_RSU.json +++ b/data/rxMsg_TIM_GeneratedBy_RSU.json @@ -1,243 +1,243 @@ -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519354,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":239,"serialNumber":15425,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":234,"serialNumber":15420,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519355,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":242,"serialNumber":15428,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:36.195Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519355,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":241,"serialNumber":15427,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.996Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519354,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":240,"serialNumber":15426,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":238,"serialNumber":15424,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:34.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":237,"serialNumber":15423,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:34.192Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":236,"serialNumber":15422,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":235,"serialNumber":15421,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":233,"serialNumber":15419,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":232,"serialNumber":15418,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":231,"serialNumber":15417,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":230,"serialNumber":15416,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":229,"serialNumber":15415,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.691Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":228,"serialNumber":15414,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":227,"serialNumber":15413,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":226,"serialNumber":15412,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519334,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":225,"serialNumber":15411,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.592Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519334,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":224,"serialNumber":15410,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.592Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519332,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":223,"serialNumber":15409,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":222,"serialNumber":15408,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.104Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":221,"serialNumber":15407,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":220,"serialNumber":15406,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":219,"serialNumber":15405,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":218,"serialNumber":15404,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":217,"serialNumber":15403,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.392Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519324,"speed":0.04,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":216,"serialNumber":15402,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":215,"serialNumber":15401,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.902Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":214,"serialNumber":15400,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.793Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":213,"serialNumber":15399,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":212,"serialNumber":15398,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":211,"serialNumber":15397,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":210,"serialNumber":15396,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":209,"serialNumber":15395,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.593Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519299,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":208,"serialNumber":15394,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":207,"serialNumber":15393,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519295,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":206,"serialNumber":15392,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519295,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":205,"serialNumber":15391,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.792Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519294,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":204,"serialNumber":15390,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.792Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519294,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":203,"serialNumber":15389,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519292,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":202,"serialNumber":15388,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519292,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":201,"serialNumber":15387,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.191Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151929,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":200,"serialNumber":15386,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.100Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":199,"serialNumber":15385,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.391Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519275,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":196,"serialNumber":15382,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.891Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519275,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":197,"serialNumber":15383,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.100Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519277,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":198,"serialNumber":15384,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.289Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.04,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":195,"serialNumber":15381,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":194,"serialNumber":15380,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":193,"serialNumber":15379,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":192,"serialNumber":15378,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.193Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":191,"serialNumber":15377,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.193Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":190,"serialNumber":15376,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":189,"serialNumber":15375,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.692Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":185,"serialNumber":15371,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":188,"serialNumber":15374,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.590Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":187,"serialNumber":15373,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":186,"serialNumber":15372,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.788Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":184,"serialNumber":15370,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":183,"serialNumber":15369,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":182,"serialNumber":15368,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.099Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":181,"serialNumber":15367,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":180,"serialNumber":15366,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":179,"serialNumber":15365,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":178,"serialNumber":15364,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":173,"serialNumber":15359,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:16.192Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":177,"serialNumber":15363,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":176,"serialNumber":15362,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":175,"serialNumber":15361,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:17.997Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":174,"serialNumber":15360,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:17.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":172,"serialNumber":15358,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:16.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":162,"serialNumber":15348,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":171,"serialNumber":15357,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":170,"serialNumber":15356,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":169,"serialNumber":15355,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":168,"serialNumber":15354,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":167,"serialNumber":15353,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.094Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":166,"serialNumber":15352,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.991Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.06,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":165,"serialNumber":15351,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":164,"serialNumber":15350,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":163,"serialNumber":15349,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":152,"serialNumber":15338,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567223},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":161,"serialNumber":15347,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.594Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":160,"serialNumber":15346,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.492Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":159,"serialNumber":15345,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":158,"serialNumber":15344,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":157,"serialNumber":15343,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":156,"serialNumber":15342,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":155,"serialNumber":15341,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":153,"serialNumber":15339,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.394Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":154,"serialNumber":15340,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.394Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":150,"serialNumber":15336,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":151,"serialNumber":15337,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":149,"serialNumber":15335,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.693Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":148,"serialNumber":15334,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":147,"serialNumber":15333,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":146,"serialNumber":15332,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":145,"serialNumber":15331,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":136,"serialNumber":15322,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.392Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":144,"serialNumber":15330,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":143,"serialNumber":15329,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":142,"serialNumber":15328,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":141,"serialNumber":15327,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":140,"serialNumber":15326,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":139,"serialNumber":15325,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":138,"serialNumber":15324,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":137,"serialNumber":15323,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":135,"serialNumber":15321,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519299,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":134,"serialNumber":15320,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.099Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":125,"serialNumber":15311,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.595Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519299,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":133,"serialNumber":15319,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":132,"serialNumber":15318,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":131,"serialNumber":15317,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":130,"serialNumber":15316,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":129,"serialNumber":15315,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":128,"serialNumber":15314,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":127,"serialNumber":15313,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":126,"serialNumber":15312,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519315,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":123,"serialNumber":15309,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0.02,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":124,"serialNumber":15310,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.495Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519319,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":120,"serialNumber":15306,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519315,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":122,"serialNumber":15308,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519317,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":121,"serialNumber":15307,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":119,"serialNumber":15305,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":118,"serialNumber":15304,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":117,"serialNumber":15303,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":113,"serialNumber":15299,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":116,"serialNumber":15302,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.492Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519324,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":115,"serialNumber":15301,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":114,"serialNumber":15300,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":112,"serialNumber":15298,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:59.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519339,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":111,"serialNumber":15297,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:58.195Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519339,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":110,"serialNumber":15296,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:58.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":109,"serialNumber":15295,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151934,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":108,"serialNumber":15294,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.696Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":107,"serialNumber":15293,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":106,"serialNumber":15292,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":104,"serialNumber":15290,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":105,"serialNumber":15291,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":103,"serialNumber":15289,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":102,"serialNumber":15288,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":101,"serialNumber":15287,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.489Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":100,"serialNumber":15286,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":99,"serialNumber":15285,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":98,"serialNumber":15284,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.594Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":97,"serialNumber":15283,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":96,"serialNumber":15282,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":94,"serialNumber":15280,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":93,"serialNumber":15279,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":95,"serialNumber":15281,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.094Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":92,"serialNumber":15278,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.495Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":80,"serialNumber":15266,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":91,"serialNumber":15277,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.395Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":90,"serialNumber":15276,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":89,"serialNumber":15275,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":88,"serialNumber":15274,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":87,"serialNumber":15273,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":86,"serialNumber":15272,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.693Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":85,"serialNumber":15271,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.985Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":84,"serialNumber":15270,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.885Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":83,"serialNumber":15269,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":82,"serialNumber":15268,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":81,"serialNumber":15267,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":79,"serialNumber":15265,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":78,"serialNumber":15264,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.791Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":76,"serialNumber":15262,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":77,"serialNumber":15263,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.791Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":75,"serialNumber":15261,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":70,"serialNumber":15256,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":69,"serialNumber":15255,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.781Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":74,"serialNumber":15260,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.188Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":73,"serialNumber":15259,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.092Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":72,"serialNumber":15258,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:47.386Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":71,"serialNumber":15257,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:47.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":68,"serialNumber":15254,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":67,"serialNumber":15253,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.286Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":66,"serialNumber":15252,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":65,"serialNumber":15251,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":64,"serialNumber":15250,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":63,"serialNumber":15249,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":62,"serialNumber":15248,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.485Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":61,"serialNumber":15247,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":60,"serialNumber":15246,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.04,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":59,"serialNumber":15245,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":58,"serialNumber":15244,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":57,"serialNumber":15243,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.088Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":56,"serialNumber":15242,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":55,"serialNumber":15241,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.684Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":54,"serialNumber":15240,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.583Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":53,"serialNumber":15239,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.583Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":52,"serialNumber":15238,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":51,"serialNumber":15237,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.089Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":50,"serialNumber":15236,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:41.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":49,"serialNumber":15235,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:41.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":48,"serialNumber":15234,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:40.189Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":47,"serialNumber":15233,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:40.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":46,"serialNumber":15232,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567229},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":45,"serialNumber":15231,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.6567229},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":44,"serialNumber":15230,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":43,"serialNumber":15229,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":42,"serialNumber":15228,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":41,"serialNumber":15227,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.990Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519339,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":40,"serialNumber":15226,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.990Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519339,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":39,"serialNumber":15225,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519337,"speed":0,"longitude":-104.6567224},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":38,"serialNumber":15224,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519337,"speed":0,"longitude":-104.6567224},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":37,"serialNumber":15223,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.291Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0.04,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":36,"serialNumber":15222,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.586Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":35,"serialNumber":15221,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":34,"serialNumber":15220,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0.02,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":33,"serialNumber":15219,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.089Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":32,"serialNumber":15218,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":31,"serialNumber":15217,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.487Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":30,"serialNumber":15216,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":29,"serialNumber":15215,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":28,"serialNumber":15214,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.088Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":27,"serialNumber":15213,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":26,"serialNumber":15212,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.788Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":25,"serialNumber":15211,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":24,"serialNumber":15210,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.983Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":23,"serialNumber":15209,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":22,"serialNumber":15208,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":21,"serialNumber":15207,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":20,"serialNumber":15206,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":19,"serialNumber":15205,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":18,"serialNumber":15204,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":15,"serialNumber":15201,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":17,"serialNumber":15203,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":16,"serialNumber":15202,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":10,"serialNumber":15196,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.096Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":14,"serialNumber":15200,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":13,"serialNumber":15199,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.087Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":12,"serialNumber":15198,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":11,"serialNumber":15197,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":8,"serialNumber":15194,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":9,"serialNumber":15195,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.988Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":7,"serialNumber":15193,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.487Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":6,"serialNumber":15192,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":5,"serialNumber":15191,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.187Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":4,"serialNumber":15190,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.187Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":3,"serialNumber":15189,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":2,"serialNumber":15188,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":1,"serialNumber":15187,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":15186,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.484Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519354,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":239,"serialNumber":15425,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":234,"serialNumber":15420,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519355,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":242,"serialNumber":15428,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:36.195Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519355,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":241,"serialNumber":15427,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.996Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519354,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":240,"serialNumber":15426,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:35.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":238,"serialNumber":15424,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:34.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":237,"serialNumber":15423,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:34.192Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":236,"serialNumber":15422,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":235,"serialNumber":15421,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":233,"serialNumber":15419,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":232,"serialNumber":15418,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:33.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":231,"serialNumber":15417,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":230,"serialNumber":15416,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":229,"serialNumber":15415,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.691Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":228,"serialNumber":15414,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":227,"serialNumber":15413,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":226,"serialNumber":15412,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:32.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519334,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":225,"serialNumber":15411,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.592Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519334,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":224,"serialNumber":15410,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.592Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519332,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":223,"serialNumber":15409,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":222,"serialNumber":15408,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:30.104Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":221,"serialNumber":15407,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":220,"serialNumber":15406,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":219,"serialNumber":15405,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":218,"serialNumber":15404,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":217,"serialNumber":15403,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.392Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519324,"speed":0.04,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":216,"serialNumber":15402,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:29.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":215,"serialNumber":15401,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.902Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":214,"serialNumber":15400,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.793Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":213,"serialNumber":15399,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:28.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":212,"serialNumber":15398,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":211,"serialNumber":15397,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":210,"serialNumber":15396,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":209,"serialNumber":15395,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.593Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519299,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":208,"serialNumber":15394,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":207,"serialNumber":15393,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:26.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519295,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":206,"serialNumber":15392,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519295,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":205,"serialNumber":15391,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.792Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519294,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":204,"serialNumber":15390,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.792Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519294,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":203,"serialNumber":15389,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519292,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":202,"serialNumber":15388,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519292,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":201,"serialNumber":15387,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.191Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151929,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":200,"serialNumber":15386,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:25.100Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":199,"serialNumber":15385,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.391Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519275,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":196,"serialNumber":15382,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.891Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519275,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":197,"serialNumber":15383,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.100Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519277,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":198,"serialNumber":15384,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:23.289Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.04,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":195,"serialNumber":15381,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":194,"serialNumber":15380,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":193,"serialNumber":15379,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.292Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":192,"serialNumber":15378,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.193Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":191,"serialNumber":15377,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:22.193Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":190,"serialNumber":15376,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":189,"serialNumber":15375,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.692Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":185,"serialNumber":15371,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":188,"serialNumber":15374,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.590Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":187,"serialNumber":15373,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:21.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519272,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":186,"serialNumber":15372,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.788Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":184,"serialNumber":15370,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.491Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151927,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":183,"serialNumber":15369,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":182,"serialNumber":15368,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:19.099Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":181,"serialNumber":15367,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":180,"serialNumber":15366,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":179,"serialNumber":15365,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":178,"serialNumber":15364,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":173,"serialNumber":15359,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:16.192Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":177,"serialNumber":15363,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.293Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519267,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":176,"serialNumber":15362,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:18.101Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":175,"serialNumber":15361,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:17.997Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519269,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":174,"serialNumber":15360,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:17.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":172,"serialNumber":15358,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:16.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":162,"serialNumber":15348,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.290Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":171,"serialNumber":15357,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":170,"serialNumber":15356,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":169,"serialNumber":15355,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":168,"serialNumber":15354,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.048Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":167,"serialNumber":15353,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:15.094Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":166,"serialNumber":15352,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.991Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.06,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":165,"serialNumber":15351,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":164,"serialNumber":15350,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519274,"speed":0.02,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":163,"serialNumber":15349,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:14.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":152,"serialNumber":15338,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567223},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":161,"serialNumber":15347,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.594Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":160,"serialNumber":15346,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.492Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":159,"serialNumber":15345,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":158,"serialNumber":15344,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:12.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":157,"serialNumber":15343,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":156,"serialNumber":15342,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":155,"serialNumber":15341,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":153,"serialNumber":15339,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.394Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":154,"serialNumber":15340,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:11.394Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":150,"serialNumber":15336,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":151,"serialNumber":15337,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519278,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":149,"serialNumber":15335,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:10.693Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":148,"serialNumber":15334,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567213},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":147,"serialNumber":15333,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":146,"serialNumber":15332,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0.02,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":145,"serialNumber":15331,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":136,"serialNumber":15322,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.392Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":144,"serialNumber":15330,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519284,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":143,"serialNumber":15329,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:08.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":142,"serialNumber":15328,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":141,"serialNumber":15327,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519287,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":140,"serialNumber":15326,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":139,"serialNumber":15325,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":138,"serialNumber":15324,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519289,"speed":0,"longitude":-104.6567211},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":137,"serialNumber":15323,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:07.095Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519296,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":135,"serialNumber":15321,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519299,"speed":0,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":134,"serialNumber":15320,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:05.099Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":125,"serialNumber":15311,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.595Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519299,"speed":0.02,"longitude":-104.6567216},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":133,"serialNumber":15319,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":132,"serialNumber":15318,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.15193,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":131,"serialNumber":15317,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":130,"serialNumber":15316,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519302,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":129,"serialNumber":15315,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.194Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":128,"serialNumber":15314,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:04.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519304,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":127,"serialNumber":15313,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":126,"serialNumber":15312,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519315,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":123,"serialNumber":15309,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519305,"speed":0.02,"longitude":-104.6567221},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":124,"serialNumber":15310,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:03.495Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519319,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":120,"serialNumber":15306,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519315,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":122,"serialNumber":15308,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519317,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":121,"serialNumber":15307,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:01.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151932,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":119,"serialNumber":15305,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":118,"serialNumber":15304,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.694Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":117,"serialNumber":15303,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":113,"serialNumber":15299,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":116,"serialNumber":15302,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.492Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519324,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":115,"serialNumber":15301,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":114,"serialNumber":15300,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:01:00.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":112,"serialNumber":15298,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:59.893Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519339,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":111,"serialNumber":15297,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:58.195Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519339,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":110,"serialNumber":15296,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:58.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":109,"serialNumber":15295,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.890Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151934,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":108,"serialNumber":15294,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.696Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":107,"serialNumber":15293,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.493Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":106,"serialNumber":15292,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":104,"serialNumber":15290,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.994Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":105,"serialNumber":15291,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:57.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519342,"speed":0.02,"longitude":-104.656724},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":103,"serialNumber":15289,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":102,"serialNumber":15288,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":101,"serialNumber":15287,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.489Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":100,"serialNumber":15286,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519344,"speed":0.02,"longitude":-104.6567238},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":99,"serialNumber":15285,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:56.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":98,"serialNumber":15284,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.594Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":97,"serialNumber":15283,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.494Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":96,"serialNumber":15282,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":94,"serialNumber":15280,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":93,"serialNumber":15279,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519347,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":95,"serialNumber":15281,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:54.094Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":92,"serialNumber":15278,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.495Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":80,"serialNumber":15266,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":91,"serialNumber":15277,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.395Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":90,"serialNumber":15276,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.294Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":89,"serialNumber":15275,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:53.098Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":88,"serialNumber":15274,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":87,"serialNumber":15273,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.794Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.047Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567235},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":86,"serialNumber":15272,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:52.693Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":85,"serialNumber":15271,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.985Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.1519349,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":84,"serialNumber":15270,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.885Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":83,"serialNumber":15269,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":82,"serialNumber":15268,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":81,"serialNumber":15267,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:50.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1811,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":79,"serialNumber":15265,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":78,"serialNumber":15264,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.791Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":76,"serialNumber":15262,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.6567233},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":77,"serialNumber":15263,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.791Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":75,"serialNumber":15261,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":70,"serialNumber":15256,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":69,"serialNumber":15255,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.781Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":74,"serialNumber":15260,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.188Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":73,"serialNumber":15259,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:49.092Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":72,"serialNumber":15258,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:47.386Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":71,"serialNumber":15257,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:47.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.151935,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":68,"serialNumber":15254,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":67,"serialNumber":15253,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.286Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":66,"serialNumber":15252,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:46.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":65,"serialNumber":15251,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":64,"serialNumber":15250,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519349,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":63,"serialNumber":15249,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.588Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519347,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":62,"serialNumber":15248,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:45.485Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":61,"serialNumber":15247,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":60,"serialNumber":15246,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.04,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":59,"serialNumber":15245,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.488Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":58,"serialNumber":15244,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":57,"serialNumber":15243,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:43.088Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":56,"serialNumber":15242,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":55,"serialNumber":15241,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.684Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":54,"serialNumber":15240,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.583Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":53,"serialNumber":15239,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.583Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":52,"serialNumber":15238,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":51,"serialNumber":15237,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:42.089Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0.02,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":50,"serialNumber":15236,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:41.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":49,"serialNumber":15235,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:41.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":48,"serialNumber":15234,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:40.189Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":47,"serialNumber":15233,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:40.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519345,"speed":0,"longitude":-104.656723},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":46,"serialNumber":15232,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519344,"speed":0,"longitude":-104.6567229},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":45,"serialNumber":15231,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.688Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.6567229},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":44,"serialNumber":15230,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.490Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519342,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":43,"serialNumber":15229,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.6567228},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":42,"serialNumber":15228,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:39.093Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151934,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":41,"serialNumber":15227,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.990Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519339,"speed":0,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":40,"serialNumber":15226,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.990Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519339,"speed":0.02,"longitude":-104.6567226},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":39,"serialNumber":15225,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519337,"speed":0,"longitude":-104.6567224},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":38,"serialNumber":15224,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.389Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519337,"speed":0,"longitude":-104.6567224},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":37,"serialNumber":15223,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:38.291Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0.04,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":36,"serialNumber":15222,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.586Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.151933,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":35,"serialNumber":15221,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":34,"serialNumber":15220,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0.02,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":33,"serialNumber":15219,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:36.089Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.046Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519329,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":32,"serialNumber":15218,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":31,"serialNumber":15217,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.487Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":30,"serialNumber":15216,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":29,"serialNumber":15215,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":28,"serialNumber":15214,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:35.088Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":27,"serialNumber":15213,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":26,"serialNumber":15212,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.788Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":25,"serialNumber":15211,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:34.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567215},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":24,"serialNumber":15210,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.983Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":23,"serialNumber":15209,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.886Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":22,"serialNumber":15208,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":21,"serialNumber":15207,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567217},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":20,"serialNumber":15206,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:32.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":19,"serialNumber":15205,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":18,"serialNumber":15204,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.887Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":15,"serialNumber":15201,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":17,"serialNumber":15203,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.787Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":16,"serialNumber":15202,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.486Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":10,"serialNumber":15196,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.096Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000081AAA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411573054,"long":-1044928436},"name":"eastbound_I-80_379.0_380.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}},{"delta":{"node-LatLon":{"lon":-1044890201,"lat":411572261}}},{"delta":{"node-LatLon":{"lon":-1044871091,"lat":411571850}}},{"delta":{"node-LatLon":{"lon":-1044851981,"lat":411571457}}},{"delta":{"node-LatLon":{"lon":-1044832871,"lat":411571067}}},{"delta":{"node-LatLon":{"lon":-1044813761,"lat":411570655}}},{"delta":{"node-LatLon":{"lon":-1044794652,"lat":411570244}}},{"delta":{"node-LatLon":{"lon":-1044775541,"lat":411569866}}},{"delta":{"node-LatLon":{"lon":-1044756432,"lat":411569443}}},{"delta":{"node-LatLon":{"lon":-1044737322,"lat":411569043}}},{"delta":{"node-LatLon":{"lon":-1044718213,"lat":411568644}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411573054,"long":-1044928436}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0.02,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":14,"serialNumber":15200,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.186Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519322,"speed":0,"longitude":-104.6567218},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":13,"serialNumber":15199,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:31.087Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":12,"serialNumber":15198,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.387Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"00000000000010B214","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411410646,"long":-1046936213},"name":"westbound_I-80_368.0_367.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046967842,"lat":411394327}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1046999559,"lat":411378060}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047031205,"lat":411361716}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047062868,"lat":411345392}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047096133,"lat":411331062}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411410646,"long":-1046936213}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":11,"serialNumber":15197,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:29.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000035517","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":8,"serialNumber":15194,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000508A4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411245470,"long":-1047455202},"name":"westbound_I-80_365.0_364.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047493648,"lat":411244843}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047532627,"lat":411244194}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047571608,"lat":411243579}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047610587,"lat":411242950}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047649564,"lat":411242241}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411245470,"long":-1047455202}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.6567222},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":9,"serialNumber":15195,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.988Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000E2B9A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411581430,"long":-1046078669},"name":"eastbound_I-80_373.0_374.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046040217,"lat":411581285}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1046001979,"lat":411581155}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045963741,"lat":411580987}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045925503,"lat":411580842}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045887265,"lat":411580672}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411581430,"long":-1046078669}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":7,"serialNumber":15193,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.487Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456160,"packetID":"00000000000009E30E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4103}},{"item":{"itis":7986}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456160}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519325,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":6,"serialNumber":15192,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.287Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449042,"packetID":"000000000000030BDA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411577030,"long":-1045119733},"name":"eastbound_I-80_378.0_379.0_RSU-10.145.1.100_RW_4441","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045100561,"lat":411576627}}},{"delta":{"node-LatLon":{"lon":-1045081436,"lat":411576238}}},{"delta":{"node-LatLon":{"lon":-1045062310,"lat":411575844}}},{"delta":{"node-LatLon":{"lon":-1045043186,"lat":411575439}}},{"delta":{"node-LatLon":{"lon":-1045024060,"lat":411575050}}},{"delta":{"node-LatLon":{"lon":-1045004934,"lat":411574675}}},{"delta":{"node-LatLon":{"lon":-1044985812,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1044966686,"lat":411573844}}},{"delta":{"node-LatLon":{"lon":-1044947561,"lat":411573453}}},{"delta":{"node-LatLon":{"lon":-1044928436,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1044909311,"lat":411572667}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411577030,"long":-1045119733}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":5,"serialNumber":15191,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.187Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"00000000000001EA5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411575181,"long":-1044164112},"name":"eastbound_I-80_383.0_384.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1044145168,"lat":411575246}}},{"delta":{"node-LatLon":{"lon":-1044124211,"lat":411575175}}},{"delta":{"node-LatLon":{"lon":-1044103254,"lat":411575118}}},{"delta":{"node-LatLon":{"lon":-1044082297,"lat":411575045}}},{"delta":{"node-LatLon":{"lon":-1044061340,"lat":411574945}}},{"delta":{"node-LatLon":{"lon":-1044040382,"lat":411574869}}},{"delta":{"node-LatLon":{"lon":-1044019425,"lat":411574797}}},{"delta":{"node-LatLon":{"lon":-1043998468,"lat":411574703}}},{"delta":{"node-LatLon":{"lon":-1043977511,"lat":411574635}}},{"delta":{"node-LatLon":{"lon":-1043956554,"lat":411574561}}},{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411575181,"long":-1044164112}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":4,"serialNumber":15190,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:28.187Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":456159,"packetID":"000000000000037CC2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411560366,"long":-1046609462},"name":"westbound_I-80_360.0_370.0_RSU-10.145.1.100_P_Parking49251","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046627337,"lat":411555355}}},{"delta":{"node-LatLon":{"lon":-1046662642,"lat":411543930}}},{"delta":{"node-LatLon":{"lon":-1046696936,"lat":411530868}}},{"delta":{"node-LatLon":{"lon":-1046730136,"lat":411516279}}},{"delta":{"node-LatLon":{"lon":-1046762192,"lat":411500289}}},{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}},{"delta":{"node-LatLon":{"lon":-1046983702,"lat":411386195}}},{"delta":{"node-LatLon":{"lon":-1047015354,"lat":411369858}}},{"delta":{"node-LatLon":{"lon":-1047047036,"lat":411353553}}},{"delta":{"node-LatLon":{"lon":-1047079141,"lat":411337750}}},{"delta":{"node-LatLon":{"lon":-1047113459,"lat":411324878}}},{"delta":{"node-LatLon":{"lon":-1047148107,"lat":411312583}}},{"delta":{"node-LatLon":{"lon":-1047182765,"lat":411300305}}},{"delta":{"node-LatLon":{"lon":-1047217414,"lat":411288015}}},{"delta":{"node-LatLon":{"lon":-1047252075,"lat":411275744}}},{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}},{"delta":{"node-LatLon":{"lon":-1047513139,"lat":411244544}}},{"delta":{"node-LatLon":{"lon":-1047552117,"lat":411243884}}},{"delta":{"node-LatLon":{"lon":-1047591098,"lat":411243275}}},{"delta":{"node-LatLon":{"lon":-1047630076,"lat":411242612}}},{"delta":{"node-LatLon":{"lon":-1047669050,"lat":411241839}}},{"delta":{"node-LatLon":{"lon":-1047716034,"lat":411239159}}},{"delta":{"node-LatLon":{"lon":-1047754428,"lat":411234150}}},{"delta":{"node-LatLon":{"lon":-1047792686,"lat":411228560}}},{"delta":{"node-LatLon":{"lon":-1047830949,"lat":411222991}}},{"delta":{"node-LatLon":{"lon":-1047869197,"lat":411217366}}},{"delta":{"node-LatLon":{"lon":-1047906232,"lat":411211994}}},{"delta":{"node-LatLon":{"lon":-1047943264,"lat":411206611}}},{"delta":{"node-LatLon":{"lon":-1047980283,"lat":411201179}}},{"delta":{"node-LatLon":{"lon":-1048017303,"lat":411195751}}},{"delta":{"node-LatLon":{"lon":-1048054337,"lat":411190378}}},{"delta":{"node-LatLon":{"lon":-1048091850,"lat":411184891}}},{"delta":{"node-LatLon":{"lon":-1048129373,"lat":411179446}}},{"delta":{"node-LatLon":{"lon":-1048166879,"lat":411173932}}},{"delta":{"node-LatLon":{"lon":-1048204394,"lat":411168456}}},{"delta":{"node-LatLon":{"lon":-1048242230,"lat":411164679}}},{"delta":{"node-LatLon":{"lon":-1048280747,"lat":411164538}}},{"delta":{"node-LatLon":{"lon":-1048319268,"lat":411164579}}},{"delta":{"node-LatLon":{"lon":-1048357788,"lat":411164610}}},{"delta":{"node-LatLon":{"lon":-1048396210,"lat":411162963}}},{"delta":{"node-LatLon":{"lon":-1048433676,"lat":411156324}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":120,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411560366,"long":-1046609462}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":7986}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":456159}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":3,"serialNumber":15189,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.888Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449043,"packetID":"0000000000000CCD74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411574561,"long":-1043956554},"name":"eastbound_I-80_384.0_385.0_RSU-10.145.1.100_RW_4444","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1043935597,"lat":411574492}}},{"delta":{"node-LatLon":{"lon":-1043918216,"lat":411574420}}},{"delta":{"node-LatLon":{"lon":-1043900835,"lat":411574359}}},{"delta":{"node-LatLon":{"lon":-1043883454,"lat":411574286}}},{"delta":{"node-LatLon":{"lon":-1043866073,"lat":411574217}}},{"delta":{"node-LatLon":{"lon":-1043848693,"lat":411574157}}},{"delta":{"node-LatLon":{"lon":-1043831312,"lat":411574075}}},{"delta":{"node-LatLon":{"lon":-1043813931,"lat":411574033}}},{"delta":{"node-LatLon":{"lon":-1043796550,"lat":411573959}}},{"delta":{"node-LatLon":{"lon":-1043779169,"lat":411573892}}},{"delta":{"node-LatLon":{"lon":-1043761788,"lat":411573828}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411574561,"long":-1043956554}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":2,"serialNumber":15188,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.687Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449040,"packetID":"0000000000000202F0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411580672,"long":-1045887265},"name":"eastbound_I-80_374.0_375.0_RSU-10.145.1.100_RW_4438","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045849012,"lat":411580520}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045810744,"lat":411580371}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045772475,"lat":411580179}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045734206,"lat":411580127}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045695937,"lat":411580101}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411580672,"long":-1045887265}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":1025}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":1,"serialNumber":15187,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.587Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449088,"packetID":"000000000000086B2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411492107,"long":-1046778055},"name":"westbound_I-80_369.0_368.0_RSU-10.145.1.100_RW_4453","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046793931,"lat":411483939}}},{"delta":{"node-LatLon":{"lon":-1046809732,"lat":411475785}}},{"delta":{"node-LatLon":{"lon":-1046825568,"lat":411467670}}},{"delta":{"node-LatLon":{"lon":-1046841365,"lat":411459513}}},{"delta":{"node-LatLon":{"lon":-1046857165,"lat":411451359}}},{"delta":{"node-LatLon":{"lon":-1046872977,"lat":411443219}}},{"delta":{"node-LatLon":{"lon":-1046888778,"lat":411435066}}},{"delta":{"node-LatLon":{"lon":-1046904584,"lat":411426919}}},{"delta":{"node-LatLon":{"lon":-1046920416,"lat":411418801}}},{"delta":{"node-LatLon":{"lon":-1046936213,"lat":411410646}}},{"delta":{"node-LatLon":{"lon":-1046952038,"lat":411402520}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000100000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411492107,"long":-1046778055}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13580}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":297.8,"latitude":41.1519327,"speed":0.02,"longitude":-104.656722},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":15186,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":243,"bundleId":76},"sanitized":false,"recordGeneratedAt":"2018-11-14T16:00:27.484Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_RSU.gz","odeReceivedAt":"2019-04-09T18:10:23.045Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411269876,"long":-1047269563},"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000010000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411269876,"long":-1047269563}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":448260}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} diff --git a/data/rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.json b/data/rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.json index 089a9ecaa..558098c96 100644 --- a/data/rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.json +++ b/data/rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.json @@ -1,166 +1,166 @@ -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1842,"heading":270.4,"latitude":41.1164581,"speed":32.42,"longitude":-104.8309594},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":165,"serialNumber":15594,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:16:06.891Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1842,"heading":270.15,"latitude":41.1164558,"speed":32.92,"longitude":-104.8270153},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":164,"serialNumber":15593,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:15:56.582Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1827,"heading":259.0875,"latitude":41.120215,"speed":34.06,"longitude":-104.7970612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":163,"serialNumber":15592,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:37.988Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.9,"latitude":41.1203737,"speed":34.14,"longitude":-104.7959839},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":162,"serialNumber":15591,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.384Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000C4306","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415413487,"long":-1060812632},"name":"westbound_I80_272.06_279.86_SAT-84FB2473_RC_ARLI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060824406,"lat":415424958}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415413487,"long":-1060812632}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":50}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.95,"latitude":41.1203855,"speed":34.18,"longitude":-104.7959041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":159,"serialNumber":15588,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.206Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000EA327","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416355008,"long":-1062867209},"name":"eastbound_I80_267.19_272.06_SAT-7ECE7CF3_RC_ARLI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062727519,"lat":416279817}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062690294,"lat":416271928}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062652620,"lat":416264564}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062614940,"lat":416257216}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062577255,"lat":416249886}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062539573,"lat":416242549}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062501815,"lat":416235141}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062464244,"lat":416227007}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062429289,"lat":416213939}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062398699,"lat":416195722}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062373783,"lat":416173151}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062353839,"lat":416148895}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062334576,"lat":416125335}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062315283,"lat":416101788}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062296038,"lat":416078220}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062276808,"lat":416054645}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062257093,"lat":416030536}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062236012,"lat":416006340}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062206968,"lat":415987559}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062171008,"lat":415977603}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062132565,"lat":415976300}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062093782,"lat":415976349}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416355008,"long":-1062867209}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.9,"latitude":41.1203737,"speed":34.14,"longitude":-104.7959839},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":161,"serialNumber":15590,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.285Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"00000000000010847D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415976300,"long":-1062132565},"name":"eastbound_I80_272.06_279.86_SAT-A456B6BD_RC_ARLI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060830479,"lat":415423609}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415976300,"long":-1062132565}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.95,"latitude":41.1203855,"speed":34.18,"longitude":-104.7959041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":160,"serialNumber":15589,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.285Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000EF64E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415981013,"long":-1062070609},"name":"westbound_I80_267.19_272.06_SAT-1F82D7A2_RC_ARLI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062090421,"lat":415980971}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062129021,"lat":415980789}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415981013,"long":-1062070609}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":56}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":259.1,"latitude":41.1204147,"speed":34.18,"longitude":-104.7957042},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":158,"serialNumber":15587,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:34.686Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31632,"packetID":"0000000000000F6CF3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412309017,"long":-1054379125},"name":"eastbound_I80_323.85_325.82_SAT-0405F53D_VSL_V002136","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054387340,"lat":412253070}}},{"delta":{"node-LatLon":{"lon":-1054384188,"lat":412238776}}},{"delta":{"node-LatLon":{"lon":-1054383083,"lat":412224323}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054389797,"lat":412195863}}},{"delta":{"node-LatLon":{"lon":-1054394498,"lat":412181812}}},{"delta":{"node-LatLon":{"lon":-1054399238,"lat":412167769}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054408711,"lat":412139682}}},{"delta":{"node-LatLon":{"lon":-1054413260,"lat":412125813}}},{"delta":{"node-LatLon":{"lon":-1054415782,"lat":412111677}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054408252,"lat":412083905}}},{"delta":{"node-LatLon":{"lon":-1054400204,"lat":412070975}}},{"delta":{"node-LatLon":{"lon":-1054391746,"lat":412058198}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054370810,"lat":412034419}}},{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001110000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412309017,"long":-1054379125}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31632}},"msgCnt":21}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1823,"heading":258.9125,"latitude":41.1207321,"speed":34.16,"longitude":-104.7935083},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":157,"serialNumber":15586,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:29.216Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31632,"packetID":"0000000000000E347A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412822611,"long":-1055185238},"name":"eastbound_I80_317.68_323.85_SAT-E7615079_VSL_V002118","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054370239,"lat":412350939}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111110000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412822611,"long":-1055185238}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31632}},"msgCnt":24}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1823,"heading":258.95,"latitude":41.1208274,"speed":34.16,"longitude":-104.7928706},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":156,"serialNumber":15585,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:27.595Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1805,"heading":268.9125,"latitude":41.1243603,"speed":34.06,"longitude":-104.7570576},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":155,"serialNumber":15584,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:12:58.605Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1788,"heading":245.6375,"latitude":41.1273721,"speed":34.2,"longitude":-104.7257668},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":154,"serialNumber":15583,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:11:40.212Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.8125,"latitude":41.1407438,"speed":34.14,"longitude":-104.6942247},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":150,"serialNumber":15579,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:10.898Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.7625,"latitude":41.1407266,"speed":34.18,"longitude":-104.6942583},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":151,"serialNumber":15580,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:10.997Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":5}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1787,"heading":245.0375,"latitude":41.1287356,"speed":34.1,"longitude":-104.7218965},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":153,"serialNumber":15582,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:11:29.798Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.8125,"latitude":41.1406572,"speed":34.14,"longitude":-104.6943927},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":152,"serialNumber":15581,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:11.497Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":242.75,"latitude":41.1563554,"speed":27.74,"longitude":-104.6602258},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":148,"serialNumber":15577,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:08:31.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.7375,"latitude":41.1504085,"speed":10.58,"longitude":-104.6569867},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":145,"serialNumber":15574,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:04.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"00000000000004865E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410974214,"long":-1051103433},"name":"eastbound_I80_345.9_349.15_SAT-2D188807_VSL_V002275","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1051046217,"lat":410971780}}},{"delta":{"node-LatLon":{"lon":-1051027336,"lat":410973993}}},{"delta":{"node-LatLon":{"lon":-1051008857,"lat":410977669}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050972405,"lat":410986387}}},{"delta":{"node-LatLon":{"lon":-1050953820,"lat":410989753}}},{"delta":{"node-LatLon":{"lon":-1050934905,"lat":410991795}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050896815,"lat":410994269}}},{"delta":{"node-LatLon":{"lon":-1050877759,"lat":410995411}}},{"delta":{"node-LatLon":{"lon":-1050858673,"lat":410996615}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050820456,"lat":410998476}}},{"delta":{"node-LatLon":{"lon":-1050801305,"lat":410998519}}},{"delta":{"node-LatLon":{"lon":-1050782155,"lat":410998320}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050743855,"lat":410997929}}},{"delta":{"node-LatLon":{"lon":-1050724706,"lat":410997718}}},{"delta":{"node-LatLon":{"lon":-1050705556,"lat":410997530}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050667295,"lat":410997427}}},{"delta":{"node-LatLon":{"lon":-1050648246,"lat":410998545}}},{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050591949,"lat":411006727}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050554451,"lat":411012343}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050516970,"lat":411018025}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410974214,"long":-1051103433}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1813,"heading":235.65,"latitude":41.1425286,"speed":34.22,"longitude":-104.6907602},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":149,"serialNumber":15578,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:00.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":24.8125,"latitude":41.1514708,"speed":15.66,"longitude":-104.6561164},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":147,"serialNumber":15576,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:13.987Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":33.1625,"latitude":41.1504928,"speed":11.56,"longitude":-104.656914},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":146,"serialNumber":15575,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:05.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000E71AE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411217079,"long":-1052895308},"name":"eastbound_I80_336.16_339.86_SAT-3150A15C_VSL_V002214","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052878140,"lat":411209333}}},{"delta":{"node-LatLon":{"lon":-1052861535,"lat":411200909}}},{"delta":{"node-LatLon":{"lon":-1052844985,"lat":411192422}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052811861,"lat":411175478}}},{"delta":{"node-LatLon":{"lon":-1052795294,"lat":411167011}}},{"delta":{"node-LatLon":{"lon":-1052778775,"lat":411158491}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052745689,"lat":411141506}}},{"delta":{"node-LatLon":{"lon":-1052728865,"lat":411133341}}},{"delta":{"node-LatLon":{"lon":-1052712029,"lat":411126535}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052676657,"lat":411115670}}},{"delta":{"node-LatLon":{"lon":-1052658860,"lat":411110441}}},{"delta":{"node-LatLon":{"lon":-1052641069,"lat":411105200}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052605463,"lat":411094765}}},{"delta":{"node-LatLon":{"lon":-1052587658,"lat":411089552}}},{"delta":{"node-LatLon":{"lon":-1052569865,"lat":411084315}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052534102,"lat":411073877}}},{"delta":{"node-LatLon":{"lon":-1052516080,"lat":411068778}}},{"delta":{"node-LatLon":{"lon":-1052497957,"lat":411063891}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052461302,"lat":411055044}}},{"delta":{"node-LatLon":{"lon":-1052442589,"lat":411051677}}},{"delta":{"node-LatLon":{"lon":-1052423634,"lat":411049202}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052385309,"lat":411046833}}},{"delta":{"node-LatLon":{"lon":-1052366071,"lat":411046704}}},{"delta":{"node-LatLon":{"lon":-1052346951,"lat":411046651}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052308709,"lat":411046714}}},{"delta":{"node-LatLon":{"lon":-1052289589,"lat":411046568}}},{"delta":{"node-LatLon":{"lon":-1052270529,"lat":411045480}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052233174,"lat":411039476}}},{"delta":{"node-LatLon":{"lon":-1052215223,"lat":411034508}}},{"delta":{"node-LatLon":{"lon":-1052197936,"lat":411028337}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411217079,"long":-1052895308}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.65,"latitude":41.1504005,"speed":10.48,"longitude":-104.6569936},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":144,"serialNumber":15573,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"000000000000019963","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410982319,"long":-1051615463},"name":"eastbound_I80_343.24_345.9_SAT-7C287339_VSL_V002255","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}},{"delta":{"node-LatLon":{"lon":-1051560307,"lat":410993246}}},{"delta":{"node-LatLon":{"lon":-1051541730,"lat":410996259}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051503871,"lat":410998228}}},{"delta":{"node-LatLon":{"lon":-1051484919,"lat":410997224}}},{"delta":{"node-LatLon":{"lon":-1051466104,"lat":410995204}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051428300,"lat":410990965}}},{"delta":{"node-LatLon":{"lon":-1051409297,"lat":410988823}}},{"delta":{"node-LatLon":{"lon":-1051390243,"lat":410986964}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051351924,"lat":410984978}}},{"delta":{"node-LatLon":{"lon":-1051332714,"lat":410985049}}},{"delta":{"node-LatLon":{"lon":-1051313512,"lat":410985509}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051275112,"lat":410986528}}},{"delta":{"node-LatLon":{"lon":-1051255905,"lat":410986855}}},{"delta":{"node-LatLon":{"lon":-1051236694,"lat":410986784}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051198327,"lat":410985247}}},{"delta":{"node-LatLon":{"lon":-1051179211,"lat":410983796}}},{"delta":{"node-LatLon":{"lon":-1051160152,"lat":410981958}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051122310,"lat":410976921}}},{"delta":{"node-LatLon":{"lon":-1051103433,"lat":410974214}}},{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410982319,"long":-1051615463}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.75,"latitude":41.1503925,"speed":10.4,"longitude":-104.6570004},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":143,"serialNumber":15572,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.895Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000D7A5F","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411039476,"long":-1052233174},"name":"eastbound_I80_339.86_343.24_SAT-C920DC35_VSL_V002234","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052215223,"lat":411034508}}},{"delta":{"node-LatLon":{"lon":-1052197936,"lat":411028337}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052164942,"lat":411013681}}},{"delta":{"node-LatLon":{"lon":-1052148522,"lat":411006239}}},{"delta":{"node-LatLon":{"lon":-1052132112,"lat":410998785}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052099402,"lat":410983743}}},{"delta":{"node-LatLon":{"lon":-1052083431,"lat":410975763}}},{"delta":{"node-LatLon":{"lon":-1052067516,"lat":410967720}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1052032886,"lat":410955603}}},{"delta":{"node-LatLon":{"lon":-1052014286,"lat":410952254}}},{"delta":{"node-LatLon":{"lon":-1051995357,"lat":410950942}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051957579,"lat":410953842}}},{"delta":{"node-LatLon":{"lon":-1051938862,"lat":410956431}}},{"delta":{"node-LatLon":{"lon":-1051920112,"lat":410958875}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051882249,"lat":410961626}}},{"delta":{"node-LatLon":{"lon":-1051863254,"lat":410962462}}},{"delta":{"node-LatLon":{"lon":-1051844258,"lat":410963288}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051806052,"lat":410964852}}},{"delta":{"node-LatLon":{"lon":-1051786867,"lat":410965906}}},{"delta":{"node-LatLon":{"lon":-1051767713,"lat":410967235}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051729481,"lat":410970472}}},{"delta":{"node-LatLon":{"lon":-1051710370,"lat":410972125}}},{"delta":{"node-LatLon":{"lon":-1051691247,"lat":410973695}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051653026,"lat":410977005}}},{"delta":{"node-LatLon":{"lon":-1051634017,"lat":410979217}}},{"delta":{"node-LatLon":{"lon":-1051615463,"lat":410982319}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411039476,"long":-1052233174}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.8375,"latitude":41.1503846,"speed":10.24,"longitude":-104.6570069},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":142,"serialNumber":15571,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.795Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000CBE5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411072254,"long":-1052512418},"name":"westbound_I80_338.1_334.3_SAT-6073BA35_VSL_V002226","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052530201,"lat":411077493}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052565806,"lat":411087956}}},{"delta":{"node-LatLon":{"lon":-1052583610,"lat":411093218}}},{"delta":{"node-LatLon":{"lon":-1052601439,"lat":411098430}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052637078,"lat":411108892}}},{"delta":{"node-LatLon":{"lon":-1052654889,"lat":411114140}}},{"delta":{"node-LatLon":{"lon":-1052672710,"lat":411119370}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052708153,"lat":411130194}}},{"delta":{"node-LatLon":{"lon":-1052725070,"lat":411136916}}},{"delta":{"node-LatLon":{"lon":-1052741814,"lat":411145056}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052774845,"lat":411161873}}},{"delta":{"node-LatLon":{"lon":-1052791339,"lat":411170306}}},{"delta":{"node-LatLon":{"lon":-1052807830,"lat":411178743}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052840856,"lat":411195568}}},{"delta":{"node-LatLon":{"lon":-1052857346,"lat":411204006}}},{"delta":{"node-LatLon":{"lon":-1052873972,"lat":411212287}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052908476,"lat":411226105}}},{"delta":{"node-LatLon":{"lon":-1052926265,"lat":411231492}}},{"delta":{"node-LatLon":{"lon":-1052944495,"lat":411235952}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1052981949,"lat":411242012}}},{"delta":{"node-LatLon":{"lon":-1053000858,"lat":411244369}}},{"delta":{"node-LatLon":{"lon":-1053019776,"lat":411246688}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}},{"delta":{"node-LatLon":{"lon":-1053076521,"lat":411253681}}},{"delta":{"node-LatLon":{"lon":-1053095502,"lat":411255432}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053133604,"lat":411258022}}},{"delta":{"node-LatLon":{"lon":-1053152654,"lat":411259322}}},{"delta":{"node-LatLon":{"lon":-1053171705,"lat":411260611}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053209808,"lat":411263198}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411072254,"long":-1052512418}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.9375,"latitude":41.150377,"speed":10.18,"longitude":-104.6570136},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":141,"serialNumber":15570,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.795Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"000000000000025AF6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410964119,"long":-1051880840},"name":"westbound_I80_341.6_338.1_SAT-540A458A_VSL_V002247","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051918620,"lat":410961452}}},{"delta":{"node-LatLon":{"lon":-1051937339,"lat":410959095}}},{"delta":{"node-LatLon":{"lon":-1051956011,"lat":410956529}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1051993632,"lat":410953204}}},{"delta":{"node-LatLon":{"lon":-1052012535,"lat":410954343}}},{"delta":{"node-LatLon":{"lon":-1052031026,"lat":410957479}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052065392,"lat":410969376}}},{"delta":{"node-LatLon":{"lon":-1052081156,"lat":410977355}}},{"delta":{"node-LatLon":{"lon":-1052097000,"lat":410985243}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052129309,"lat":411000279}}},{"delta":{"node-LatLon":{"lon":-1052145586,"lat":411007645}}},{"delta":{"node-LatLon":{"lon":-1052161846,"lat":411015033}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052194841,"lat":411029703}}},{"delta":{"node-LatLon":{"lon":-1052212178,"lat":411036116}}},{"delta":{"node-LatLon":{"lon":-1052230242,"lat":411041252}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052267858,"lat":411047647}}},{"delta":{"node-LatLon":{"lon":-1052287100,"lat":411048748}}},{"delta":{"node-LatLon":{"lon":-1052306402,"lat":411048858}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052345008,"lat":411049101}}},{"delta":{"node-LatLon":{"lon":-1052364312,"lat":411049135}}},{"delta":{"node-LatLon":{"lon":-1052383393,"lat":411049206}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052421426,"lat":411051319}}},{"delta":{"node-LatLon":{"lon":-1052440234,"lat":411053738}}},{"delta":{"node-LatLon":{"lon":-1052458744,"lat":411057225}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052494624,"lat":411067040}}},{"delta":{"node-LatLon":{"lon":-1052512418,"lat":411072254}}},{"delta":{"node-LatLon":{"lon":-1052530201,"lat":411077493}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410964119,"long":-1051880840}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.9375,"latitude":41.150377,"speed":10.18,"longitude":-104.6570136},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":140,"serialNumber":15569,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"00000000000001F426","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410988342,"long":-1051297925},"name":"westbound_I80_344.69_341.6_SAT-0D253AC5_VSL_V002266","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}},{"delta":{"node-LatLon":{"lon":-1051353366,"lat":410987336}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051390245,"lat":410989287}}},{"delta":{"node-LatLon":{"lon":-1051408562,"lat":410991189}}},{"delta":{"node-LatLon":{"lon":-1051426852,"lat":410993239}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051464077,"lat":410997440}}},{"delta":{"node-LatLon":{"lon":-1051483045,"lat":410999413}}},{"delta":{"node-LatLon":{"lon":-1051502129,"lat":411000540}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051540305,"lat":410998837}}},{"delta":{"node-LatLon":{"lon":-1051559069,"lat":410995977}}},{"delta":{"node-LatLon":{"lon":-1051577615,"lat":410992374}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051614630,"lat":410984946}}},{"delta":{"node-LatLon":{"lon":-1051633310,"lat":410981780}}},{"delta":{"node-LatLon":{"lon":-1051652234,"lat":410979420}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051690345,"lat":410976089}}},{"delta":{"node-LatLon":{"lon":-1051709415,"lat":410974522}}},{"delta":{"node-LatLon":{"lon":-1051728480,"lat":410972919}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051766615,"lat":410969748}}},{"delta":{"node-LatLon":{"lon":-1051785706,"lat":410968344}}},{"delta":{"node-LatLon":{"lon":-1051804844,"lat":410967360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051842945,"lat":410965770}}},{"delta":{"node-LatLon":{"lon":-1051861895,"lat":410964974}}},{"delta":{"node-LatLon":{"lon":-1051880840,"lat":410964119}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410988342,"long":-1051297925}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531237,"speed":0.02,"longitude":-104.6592302},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":137,"serialNumber":15566,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:05:45.221Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":33.15,"latitude":41.1503693,"speed":10.08,"longitude":-104.6570203},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":139,"serialNumber":15568,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000AB37E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411002479,"long":-1050722393},"name":"westbound_I80_347.69_344.69_SAT-3E628AB0_VSL_V002290","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050741574,"lat":411002681}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050779937,"lat":411002969}}},{"delta":{"node-LatLon":{"lon":-1050799110,"lat":411002558}}},{"delta":{"node-LatLon":{"lon":-1050818249,"lat":411001589}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050856482,"lat":410999179}}},{"delta":{"node-LatLon":{"lon":-1050875598,"lat":410997967}}},{"delta":{"node-LatLon":{"lon":-1050895063,"lat":410996770}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050933978,"lat":410994246}}},{"delta":{"node-LatLon":{"lon":-1050953322,"lat":410992263}}},{"delta":{"node-LatLon":{"lon":-1050972317,"lat":410988851}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051009569,"lat":410979971}}},{"delta":{"node-LatLon":{"lon":-1051028444,"lat":410976198}}},{"delta":{"node-LatLon":{"lon":-1051047752,"lat":410974038}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051086711,"lat":410974535}}},{"delta":{"node-LatLon":{"lon":-1051105965,"lat":410976959}}},{"delta":{"node-LatLon":{"lon":-1051125148,"lat":410979701}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051163659,"lat":410984549}}},{"delta":{"node-LatLon":{"lon":-1051183016,"lat":410986460}}},{"delta":{"node-LatLon":{"lon":-1051202450,"lat":410987845}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051241445,"lat":410989249}}},{"delta":{"node-LatLon":{"lon":-1051260967,"lat":410989237}}},{"delta":{"node-LatLon":{"lon":-1051279448,"lat":410988854}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411002479,"long":-1050722393}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":13}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":35.525,"latitude":41.1502985,"speed":8.76,"longitude":-104.6570835},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":138,"serialNumber":15567,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:02.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531242,"speed":0.02,"longitude":-104.6592305},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":136,"serialNumber":15565,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:05:33.701Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531244,"speed":0.02,"longitude":-104.6592302},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":135,"serialNumber":15564,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:04:35.702Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531259,"speed":0.02,"longitude":-104.659231},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":134,"serialNumber":15563,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:04:24.119Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":251.0625,"latitude":41.1531274,"speed":0.02,"longitude":-104.6592349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":133,"serialNumber":15562,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:00:21.777Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1821,"heading":55.6625,"latitude":41.1432762,"speed":33.68,"longitude":-104.6883421},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":132,"serialNumber":15561,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:06.352Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000B4F4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411246688,"long":-1053019776},"name":"westbound_I80_323.05_335.11_SAT-B91A2E52_RC_LARI80ECHEYBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054127454,"lat":411694572}}},{"delta":{"node-LatLon":{"lon":-1054164403,"lat":411745737}}},{"delta":{"node-LatLon":{"lon":-1054200041,"lat":411796105}}},{"delta":{"node-LatLon":{"lon":-1054218886,"lat":411851211}}},{"delta":{"node-LatLon":{"lon":-1054243815,"lat":411905185}}},{"delta":{"node-LatLon":{"lon":-1054287780,"lat":411952905}}},{"delta":{"node-LatLon":{"lon":-1054331852,"lat":412000578}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000001111}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411246688,"long":-1053019776}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5127}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1821,"heading":55.6,"latitude":41.143259,"speed":33.66,"longitude":-104.6883751},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":131,"serialNumber":15560,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:06.352Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000F25D6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412420501,"long":-1054392109},"name":"eastbound_I80_323.05_335.11_SAT-2FAB6C57_RC_LARI80ECHEYBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111110000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412420501,"long":-1054392109}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5127}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1820,"heading":55.65,"latitude":41.1429505,"speed":33.72,"longitude":-104.6889711},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":130,"serialNumber":15559,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:04.456Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000936E7","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417414634,"long":-1068269969},"name":"westbound_I80_221.2_235.23_SAT-09D8678A_RC_RAWI80ELARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068289321,"lat":417415359}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}},{"delta":{"node-LatLon":{"lon":-1068385974,"lat":417418859}}},{"delta":{"node-LatLon":{"lon":-1068463156,"lat":417421689}}},{"delta":{"node-LatLon":{"lon":-1068540338,"lat":417424515}}},{"delta":{"node-LatLon":{"lon":-1068617852,"lat":417427395}}},{"delta":{"node-LatLon":{"lon":-1068695369,"lat":417430231}}},{"delta":{"node-LatLon":{"lon":-1068772890,"lat":417433050}}},{"delta":{"node-LatLon":{"lon":-1068850417,"lat":417435830}}},{"delta":{"node-LatLon":{"lon":-1068927943,"lat":417438632}}},{"delta":{"node-LatLon":{"lon":-1069005025,"lat":417441424}}},{"delta":{"node-LatLon":{"lon":-1069082106,"lat":417444219}}},{"delta":{"node-LatLon":{"lon":-1069159408,"lat":417446974}}},{"delta":{"node-LatLon":{"lon":-1069236759,"lat":417451306}}},{"delta":{"node-LatLon":{"lon":-1069312011,"lat":417465173}}},{"delta":{"node-LatLon":{"lon":-1069385103,"lat":417484568}}},{"delta":{"node-LatLon":{"lon":-1069458135,"lat":417504094}}},{"delta":{"node-LatLon":{"lon":-1069530060,"lat":417523167}}},{"delta":{"node-LatLon":{"lon":-1069600849,"lat":417541844}}},{"delta":{"node-LatLon":{"lon":-1069673525,"lat":417555795}}},{"delta":{"node-LatLon":{"lon":-1069748966,"lat":417568966}}},{"delta":{"node-LatLon":{"lon":-1069824418,"lat":417582109}}},{"delta":{"node-LatLon":{"lon":-1069899351,"lat":417595155}}},{"delta":{"node-LatLon":{"lon":-1069973766,"lat":417608100}}},{"delta":{"node-LatLon":{"lon":-1070048170,"lat":417621086}}},{"delta":{"node-LatLon":{"lon":-1070123773,"lat":417634264}}},{"delta":{"node-LatLon":{"lon":-1070199399,"lat":417647374}}},{"delta":{"node-LatLon":{"lon":-1070274965,"lat":417660512}}},{"delta":{"node-LatLon":{"lon":-1070350472,"lat":417673678}}},{"delta":{"node-LatLon":{"lon":-1070425989,"lat":417686813}}},{"delta":{"node-LatLon":{"lon":-1070501711,"lat":417699947}}},{"delta":{"node-LatLon":{"lon":-1070577425,"lat":417713109}}},{"delta":{"node-LatLon":{"lon":-1070653637,"lat":417726293}}},{"delta":{"node-LatLon":{"lon":-1070730992,"lat":417736504}}},{"delta":{"node-LatLon":{"lon":-1070808409,"lat":417727589}}},{"delta":{"node-LatLon":{"lon":-1070884161,"lat":417718392}}},{"delta":{"node-LatLon":{"lon":-1070959940,"lat":417729715}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417414634,"long":-1068269969}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":34}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1819,"heading":55.6625,"latitude":41.1429333,"speed":33.7,"longitude":-104.6890041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":129,"serialNumber":15558,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:04.456Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"00000000000009698C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417730521,"long":-1070980675},"name":"eastbound_I80_221.2_235.23_SAT-BA88D691_RC_RAWI80ELARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1070961677,"lat":417727641}}},{"delta":{"node-LatLon":{"lon":-1070885649,"lat":417716362}}},{"delta":{"node-LatLon":{"lon":-1070809626,"lat":417725169}}},{"delta":{"node-LatLon":{"lon":-1070732756,"lat":417733042}}},{"delta":{"node-LatLon":{"lon":-1070656229,"lat":417722191}}},{"delta":{"node-LatLon":{"lon":-1070580490,"lat":417709023}}},{"delta":{"node-LatLon":{"lon":-1070504992,"lat":417695900}}},{"delta":{"node-LatLon":{"lon":-1070429493,"lat":417682786}}},{"delta":{"node-LatLon":{"lon":-1070354047,"lat":417669673}}},{"delta":{"node-LatLon":{"lon":-1070278596,"lat":417656581}}},{"delta":{"node-LatLon":{"lon":-1070202954,"lat":417643413}}},{"delta":{"node-LatLon":{"lon":-1070127097,"lat":417630244}}},{"delta":{"node-LatLon":{"lon":-1070051256,"lat":417617028}}},{"delta":{"node-LatLon":{"lon":-1069975759,"lat":417603852}}},{"delta":{"node-LatLon":{"lon":-1069900250,"lat":417590719}}},{"delta":{"node-LatLon":{"lon":-1069825529,"lat":417577695}}},{"delta":{"node-LatLon":{"lon":-1069751604,"lat":417564757}}},{"delta":{"node-LatLon":{"lon":-1069677665,"lat":417551870}}},{"delta":{"node-LatLon":{"lon":-1069603910,"lat":417538967}}},{"delta":{"node-LatLon":{"lon":-1069531945,"lat":417521380}}},{"delta":{"node-LatLon":{"lon":-1069460002,"lat":417502274}}},{"delta":{"node-LatLon":{"lon":-1069387530,"lat":417482961}}},{"delta":{"node-LatLon":{"lon":-1069315049,"lat":417463671}}},{"delta":{"node-LatLon":{"lon":-1069240161,"lat":417448143}}},{"delta":{"node-LatLon":{"lon":-1069162781,"lat":417442613}}},{"delta":{"node-LatLon":{"lon":-1069085198,"lat":417439823}}},{"delta":{"node-LatLon":{"lon":-1069007744,"lat":417437041}}},{"delta":{"node-LatLon":{"lon":-1068930291,"lat":417434237}}},{"delta":{"node-LatLon":{"lon":-1068853004,"lat":417431463}}},{"delta":{"node-LatLon":{"lon":-1068775721,"lat":417428637}}},{"delta":{"node-LatLon":{"lon":-1068698384,"lat":417425830}}},{"delta":{"node-LatLon":{"lon":-1068620993,"lat":417423054}}},{"delta":{"node-LatLon":{"lon":-1068543604,"lat":417420239}}},{"delta":{"node-LatLon":{"lon":-1068465827,"lat":417417448}}},{"delta":{"node-LatLon":{"lon":-1068388058,"lat":417414571}}},{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068291290,"lat":417411033}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417730521,"long":-1070980675}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1813,"heading":55.8,"latitude":41.1416528,"speed":33.86,"longitude":-104.6915031},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":128,"serialNumber":15557,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:52:56.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1785,"heading":64.5,"latitude":41.1294943,"speed":33.72,"longitude":-104.7183663},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":127,"serialNumber":15556,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:38.659Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1785,"heading":64.4875,"latitude":41.129429,"speed":33.72,"longitude":-104.7185478},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":126,"serialNumber":15555,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:38.064Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1786,"heading":64.4,"latitude":41.1281042,"speed":33.72,"longitude":-104.7222965},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":125,"serialNumber":15554,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:27.862Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":83.2375,"latitude":41.1237719,"speed":33.74,"longitude":-104.7710343},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":124,"serialNumber":15553,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:49:24.469Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1812,"heading":79.025,"latitude":41.1232447,"speed":33.74,"longitude":-104.7751515},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":123,"serialNumber":15552,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:49:14.272Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1847,"heading":78.975,"latitude":41.1169477,"speed":32.36,"longitude":-104.8182828},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":122,"serialNumber":15551,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:47:24.575Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1845,"heading":77.7,"latitude":41.1159012,"speed":34,"longitude":-104.8409627},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":121,"serialNumber":15550,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:46:27.777Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1849,"heading":73.9,"latitude":41.1149888,"speed":33.66,"longitude":-104.8452745},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":120,"serialNumber":15549,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:46:16.678Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1906,"heading":89.55,"latitude":41.116473,"speed":33.74,"longitude":-104.8918353},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":119,"serialNumber":15548,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:44:17.473Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1934,"heading":81.9125,"latitude":41.1133295,"speed":33.72,"longitude":-104.928415},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":118,"serialNumber":15547,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:42:45.469Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1935,"heading":81.8375,"latitude":41.112875,"speed":33.74,"longitude":-104.9328746},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":117,"serialNumber":15546,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:42:34.275Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1974,"heading":84.1875,"latitude":41.1097147,"speed":33.74,"longitude":-104.9682881},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":116,"serialNumber":15545,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:41:05.380Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2012,"heading":69.7125,"latitude":41.1052636,"speed":33.68,"longitude":-104.9975033},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":115,"serialNumber":15544,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:50.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2013,"heading":69.6,"latitude":41.1051793,"speed":33.7,"longitude":-104.9978043},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":114,"serialNumber":15543,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:50.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2023,"heading":69.3,"latitude":41.1036902,"speed":33.84,"longitude":-105.0030723},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":113,"serialNumber":15542,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:36.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2067,"heading":88.15,"latitude":41.103157,"speed":32.74,"longitude":-105.0380418},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":112,"serialNumber":15541,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:38:06.906Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2101,"heading":89.1625,"latitude":41.0997427,"speed":29.06,"longitude":-105.0669513},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":111,"serialNumber":15540,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:36:43.704Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2106,"heading":90.6,"latitude":41.0997719,"speed":29.24,"longitude":-105.072266},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":110,"serialNumber":15539,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:36:28.405Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2156,"heading":92.55,"latitude":41.0978479,"speed":18.52,"longitude":-105.114164},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":109,"serialNumber":15538,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:34:24.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.7,"latitude":41.0973887,"speed":29.26,"longitude":-105.1050253},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":108,"serialNumber":15537,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.398Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525486,"packetID":"0000000000000A59C2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410988342,"long":-1051297925},"name":"westbound_I80_344.69_341.6_RSU-10.145.13.73_VSL_V002266","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}},{"delta":{"node-LatLon":{"lon":-1051353366,"lat":410987336}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051390245,"lat":410989287}}},{"delta":{"node-LatLon":{"lon":-1051408562,"lat":410991189}}},{"delta":{"node-LatLon":{"lon":-1051426852,"lat":410993239}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051464077,"lat":410997440}}},{"delta":{"node-LatLon":{"lon":-1051483045,"lat":410999413}}},{"delta":{"node-LatLon":{"lon":-1051502129,"lat":411000540}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051540305,"lat":410998837}}},{"delta":{"node-LatLon":{"lon":-1051559069,"lat":410995977}}},{"delta":{"node-LatLon":{"lon":-1051577615,"lat":410992374}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051614630,"lat":410984946}}},{"delta":{"node-LatLon":{"lon":-1051633310,"lat":410981780}}},{"delta":{"node-LatLon":{"lon":-1051652234,"lat":410979420}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051690345,"lat":410976089}}},{"delta":{"node-LatLon":{"lon":-1051709415,"lat":410974522}}},{"delta":{"node-LatLon":{"lon":-1051728480,"lat":410972919}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051766615,"lat":410969748}}},{"delta":{"node-LatLon":{"lon":-1051785706,"lat":410968344}}},{"delta":{"node-LatLon":{"lon":-1051804844,"lat":410967360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051842945,"lat":410965770}}},{"delta":{"node-LatLon":{"lon":-1051861895,"lat":410964974}}},{"delta":{"node-LatLon":{"lon":-1051880840,"lat":410964119}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410988342,"long":-1051297925}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":525486}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.4125,"latitude":41.0973906,"speed":29.22,"longitude":-105.1049903},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":107,"serialNumber":15536,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.298Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525488,"packetID":"000000000000095E23","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410982319,"long":-1051615463},"name":"eastbound_I80_343.24_345.9_RSU-10.145.13.73_VSL_V002255","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}},{"delta":{"node-LatLon":{"lon":-1051560307,"lat":410993246}}},{"delta":{"node-LatLon":{"lon":-1051541730,"lat":410996259}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051503871,"lat":410998228}}},{"delta":{"node-LatLon":{"lon":-1051484919,"lat":410997224}}},{"delta":{"node-LatLon":{"lon":-1051466104,"lat":410995204}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051428300,"lat":410990965}}},{"delta":{"node-LatLon":{"lon":-1051409297,"lat":410988823}}},{"delta":{"node-LatLon":{"lon":-1051390243,"lat":410986964}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051351924,"lat":410984978}}},{"delta":{"node-LatLon":{"lon":-1051332714,"lat":410985049}}},{"delta":{"node-LatLon":{"lon":-1051313512,"lat":410985509}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051275112,"lat":410986528}}},{"delta":{"node-LatLon":{"lon":-1051255905,"lat":410986855}}},{"delta":{"node-LatLon":{"lon":-1051236694,"lat":410986784}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051198327,"lat":410985247}}},{"delta":{"node-LatLon":{"lon":-1051179211,"lat":410983796}}},{"delta":{"node-LatLon":{"lon":-1051160152,"lat":410981958}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051122310,"lat":410976921}}},{"delta":{"node-LatLon":{"lon":-1051103433,"lat":410974214}}},{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410982319,"long":-1051615463}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":525488}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.4125,"latitude":41.0973927,"speed":29.22,"longitude":-105.1049556},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":106,"serialNumber":15535,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.202Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525489,"packetID":"000000000000075900","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410974214,"long":-1051103433},"name":"eastbound_I80_345.9_349.15_RSU-10.145.13.73_VSL_V002275","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1051046217,"lat":410971780}}},{"delta":{"node-LatLon":{"lon":-1051027336,"lat":410973993}}},{"delta":{"node-LatLon":{"lon":-1051008857,"lat":410977669}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050972405,"lat":410986387}}},{"delta":{"node-LatLon":{"lon":-1050953820,"lat":410989753}}},{"delta":{"node-LatLon":{"lon":-1050934905,"lat":410991795}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050896815,"lat":410994269}}},{"delta":{"node-LatLon":{"lon":-1050877759,"lat":410995411}}},{"delta":{"node-LatLon":{"lon":-1050858673,"lat":410996615}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050820456,"lat":410998476}}},{"delta":{"node-LatLon":{"lon":-1050801305,"lat":410998519}}},{"delta":{"node-LatLon":{"lon":-1050782155,"lat":410998320}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050743855,"lat":410997929}}},{"delta":{"node-LatLon":{"lon":-1050724706,"lat":410997718}}},{"delta":{"node-LatLon":{"lon":-1050705556,"lat":410997530}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050667295,"lat":410997427}}},{"delta":{"node-LatLon":{"lon":-1050648246,"lat":410998545}}},{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050591949,"lat":411006727}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050554451,"lat":411012343}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050516970,"lat":411018025}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410974214,"long":-1051103433}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":525489}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.1625,"latitude":41.0973947,"speed":29.22,"longitude":-105.1049209},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":105,"serialNumber":15534,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.102Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525489,"packetID":"0000000000000B442E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411020862,"long":-1050498229},"name":"eastbound_I80_349.15_353.5_RSU-10.145.13.73_VSL_V002299","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}},{"delta":{"node-LatLon":{"lon":-1050441324,"lat":411029165}}},{"delta":{"node-LatLon":{"lon":-1050422091,"lat":411030485}}},{"delta":{"node-LatLon":{"lon":-1050402781,"lat":411030948}}},{"delta":{"node-LatLon":{"lon":-1050383473,"lat":411031428}}},{"delta":{"node-LatLon":{"lon":-1050364161,"lat":411031843}}},{"delta":{"node-LatLon":{"lon":-1050344848,"lat":411031826}}},{"delta":{"node-LatLon":{"lon":-1050325631,"lat":411030376}}},{"delta":{"node-LatLon":{"lon":-1050306653,"lat":411027659}}},{"delta":{"node-LatLon":{"lon":-1050288159,"lat":411024603}}},{"delta":{"node-LatLon":{"lon":-1050269678,"lat":411021507}}},{"delta":{"node-LatLon":{"lon":-1050251179,"lat":411018469}}},{"delta":{"node-LatLon":{"lon":-1050232676,"lat":411015448}}},{"delta":{"node-LatLon":{"lon":-1050214174,"lat":411012425}}},{"delta":{"node-LatLon":{"lon":-1050195535,"lat":411009957}}},{"delta":{"node-LatLon":{"lon":-1050176673,"lat":411008812}}},{"delta":{"node-LatLon":{"lon":-1050157751,"lat":411008904}}},{"delta":{"node-LatLon":{"lon":-1050138924,"lat":411010341}}},{"delta":{"node-LatLon":{"lon":-1050120335,"lat":411013008}}},{"delta":{"node-LatLon":{"lon":-1050102002,"lat":411016953}}},{"delta":{"node-LatLon":{"lon":-1050084082,"lat":411021875}}},{"delta":{"node-LatLon":{"lon":-1050066198,"lat":411026874}}},{"delta":{"node-LatLon":{"lon":-1050048325,"lat":411031899}}},{"delta":{"node-LatLon":{"lon":-1050030476,"lat":411036969}}},{"delta":{"node-LatLon":{"lon":-1050012604,"lat":411041995}}},{"delta":{"node-LatLon":{"lon":-1049994738,"lat":411047033}}},{"delta":{"node-LatLon":{"lon":-1049976865,"lat":411052057}}},{"delta":{"node-LatLon":{"lon":-1049959011,"lat":411057120}}},{"delta":{"node-LatLon":{"lon":-1049941141,"lat":411062151}}},{"delta":{"node-LatLon":{"lon":-1049923053,"lat":411066918}}},{"delta":{"node-LatLon":{"lon":-1049904488,"lat":411070470}}},{"delta":{"node-LatLon":{"lon":-1049885607,"lat":411072913}}},{"delta":{"node-LatLon":{"lon":-1049866692,"lat":411075206}}},{"delta":{"node-LatLon":{"lon":-1049847778,"lat":411077504}}},{"delta":{"node-LatLon":{"lon":-1049828870,"lat":411079830}}},{"delta":{"node-LatLon":{"lon":-1049809945,"lat":411082077}}},{"delta":{"node-LatLon":{"lon":-1049791039,"lat":411084415}}},{"delta":{"node-LatLon":{"lon":-1049772121,"lat":411086693}}},{"delta":{"node-LatLon":{"lon":-1049753209,"lat":411089002}}},{"delta":{"node-LatLon":{"lon":-1049734291,"lat":411091274}}},{"delta":{"node-LatLon":{"lon":-1049715382,"lat":411093589}}},{"delta":{"node-LatLon":{"lon":-1049696453,"lat":411095807}}},{"delta":{"node-LatLon":{"lon":-1049677431,"lat":411097499}}},{"delta":{"node-LatLon":{"lon":-1049658348,"lat":411098753}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411020862,"long":-1050498229}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":525489}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.1625,"latitude":41.097397,"speed":29.22,"longitude":-105.1048863},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":104,"serialNumber":15533,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.102Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525486,"packetID":"000000000000026E43","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411002479,"long":-1050722393},"name":"westbound_I80_347.69_344.69_RSU-10.145.13.73_VSL_V002290","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050741574,"lat":411002681}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050779937,"lat":411002969}}},{"delta":{"node-LatLon":{"lon":-1050799110,"lat":411002558}}},{"delta":{"node-LatLon":{"lon":-1050818249,"lat":411001589}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050856482,"lat":410999179}}},{"delta":{"node-LatLon":{"lon":-1050875598,"lat":410997967}}},{"delta":{"node-LatLon":{"lon":-1050895063,"lat":410996770}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050933978,"lat":410994246}}},{"delta":{"node-LatLon":{"lon":-1050953322,"lat":410992263}}},{"delta":{"node-LatLon":{"lon":-1050972317,"lat":410988851}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051009569,"lat":410979971}}},{"delta":{"node-LatLon":{"lon":-1051028444,"lat":410976198}}},{"delta":{"node-LatLon":{"lon":-1051047752,"lat":410974038}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051086711,"lat":410974535}}},{"delta":{"node-LatLon":{"lon":-1051105965,"lat":410976959}}},{"delta":{"node-LatLon":{"lon":-1051125148,"lat":410979701}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051163659,"lat":410984549}}},{"delta":{"node-LatLon":{"lon":-1051183016,"lat":410986460}}},{"delta":{"node-LatLon":{"lon":-1051202450,"lat":410987845}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051241445,"lat":410989249}}},{"delta":{"node-LatLon":{"lon":-1051260967,"lat":410989237}}},{"delta":{"node-LatLon":{"lon":-1051279448,"lat":410988854}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411002479,"long":-1050722393}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":525486}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":263.275,"latitude":41.0974419,"speed":29.16,"longitude":-105.1042981},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":103,"serialNumber":15532,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:11.398Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":262.5375,"latitude":41.0974641,"speed":29.2,"longitude":-105.1040569},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":102,"serialNumber":15531,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:10.599Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2066,"heading":268.2875,"latitude":41.1036482,"speed":33.28,"longitude":-105.0369024},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":99,"serialNumber":15528,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:30:09.661Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2149,"heading":252.35,"latitude":41.0983605,"speed":29.5,"longitude":-105.0994445},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":101,"serialNumber":15530,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:32:56.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2100,"heading":269.9,"latitude":41.1002133,"speed":33.28,"longitude":-105.0674061},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":100,"serialNumber":15529,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:31:27.899Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2062,"heading":278.05,"latitude":41.1035285,"speed":32.36,"longitude":-105.0326251},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":98,"serialNumber":15527,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:29:58.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2044,"heading":102.4,"latitude":41.1010291,"speed":29.68,"longitude":-105.0199132},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":97,"serialNumber":15526,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:28:29.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"notUsed2":0,"notUsed3":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025307,"speed":24.46,"longitude":-105.0468926},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":96,"serialNumber":15525,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025263,"speed":24.46,"longitude":-105.0469211},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":94,"serialNumber":15523,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31532,"packetID":"0000000000000D4252","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412846200,"long":-1055207674},"name":"eastbound_I80_317.45_323.05_SAT-5AFFFEF8_RC_LARI80ECHEYI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055196465,"lat":412834401}}},{"delta":{"node-LatLon":{"lon":-1055185238,"lat":412822611}}},{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055162838,"lat":412799002}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055139485,"lat":412775945}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055111710,"lat":412756134}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055080126,"lat":412740115}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055046853,"lat":412726244}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1055009981,"lat":412719587}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054972006,"lat":412717639}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054934016,"lat":412716179}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054896123,"lat":412717322}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054858665,"lat":412722173}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054822378,"lat":412715508}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054795466,"lat":412695384}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054770097,"lat":412673836}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054738855,"lat":412657720}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054700821,"lat":412654615}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054664843,"lat":412645844}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054634409,"lat":412628251}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054599367,"lat":412616899}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054566302,"lat":412602767}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054536736,"lat":412584610}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054507197,"lat":412566427}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054478373,"lat":412547636}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054457123,"lat":412523979}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054440857,"lat":412498114}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054424622,"lat":412472238}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054408332,"lat":412446382}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054392109,"lat":412420501}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054379237,"lat":412393551}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412846200,"long":-1055207674}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31532}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025307,"speed":24.46,"longitude":-105.0468926},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":95,"serialNumber":15524,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31534,"packetID":"0000000000000BF552","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412378541,"long":-1054372542},"name":"westbound_I80_317.45_323.05_SAT-7D6DFE3D_RC_LARI80ECHEYD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}},{"delta":{"node-LatLon":{"lon":-1054421149,"lat":412472313}}},{"delta":{"node-LatLon":{"lon":-1054429340,"lat":412485351}}},{"delta":{"node-LatLon":{"lon":-1054437555,"lat":412498379}}},{"delta":{"node-LatLon":{"lon":-1054445744,"lat":412511417}}},{"delta":{"node-LatLon":{"lon":-1054453974,"lat":412524441}}},{"delta":{"node-LatLon":{"lon":-1054463289,"lat":412537025}}},{"delta":{"node-LatLon":{"lon":-1054475122,"lat":412548474}}},{"delta":{"node-LatLon":{"lon":-1054489160,"lat":412558405}}},{"delta":{"node-LatLon":{"lon":-1054504069,"lat":412567600}}},{"delta":{"node-LatLon":{"lon":-1054519000,"lat":412576776}}},{"delta":{"node-LatLon":{"lon":-1054533896,"lat":412585985}}},{"delta":{"node-LatLon":{"lon":-1054548833,"lat":412595156}}},{"delta":{"node-LatLon":{"lon":-1054563820,"lat":412604280}}},{"delta":{"node-LatLon":{"lon":-1054579779,"lat":412612388}}},{"delta":{"node-LatLon":{"lon":-1054597055,"lat":412618777}}},{"delta":{"node-LatLon":{"lon":-1054615114,"lat":412623812}}},{"delta":{"node-LatLon":{"lon":-1054632271,"lat":412629637}}},{"delta":{"node-LatLon":{"lon":-1054647306,"lat":412638180}}},{"delta":{"node-LatLon":{"lon":-1054662004,"lat":412647078}}},{"delta":{"node-LatLon":{"lon":-1054678467,"lat":412653902}}},{"delta":{"node-LatLon":{"lon":-1054696868,"lat":412656761}}},{"delta":{"node-LatLon":{"lon":-1054715678,"lat":412657581}}},{"delta":{"node-LatLon":{"lon":-1054734355,"lat":412659287}}},{"delta":{"node-LatLon":{"lon":-1054751683,"lat":412664718}}},{"delta":{"node-LatLon":{"lon":-1054765976,"lat":412673917}}},{"delta":{"node-LatLon":{"lon":-1054778503,"lat":412684544}}},{"delta":{"node-LatLon":{"lon":-1054791379,"lat":412695492}}},{"delta":{"node-LatLon":{"lon":-1054804278,"lat":412706425}}},{"delta":{"node-LatLon":{"lon":-1054818479,"lat":412716349}}},{"delta":{"node-LatLon":{"lon":-1054835859,"lat":412722690}}},{"delta":{"node-LatLon":{"lon":-1054854996,"lat":412724695}}},{"delta":{"node-LatLon":{"lon":-1054874196,"lat":412722759}}},{"delta":{"node-LatLon":{"lon":-1054893260,"lat":412720064}}},{"delta":{"node-LatLon":{"lon":-1054912492,"lat":412718274}}},{"delta":{"node-LatLon":{"lon":-1054931875,"lat":412718613}}},{"delta":{"node-LatLon":{"lon":-1054951253,"lat":412719209}}},{"delta":{"node-LatLon":{"lon":-1054969662,"lat":412719789}}},{"delta":{"node-LatLon":{"lon":-1054987987,"lat":412721117}}},{"delta":{"node-LatLon":{"lon":-1055005745,"lat":412724757}}},{"delta":{"node-LatLon":{"lon":-1055022420,"lat":412730636}}},{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412378541,"long":-1054372542}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31534}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102522,"speed":24.46,"longitude":-105.0469496},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":93,"serialNumber":15522,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"00000000000003E132","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"eastbound_I80_111.16_130.84_SAT-DEE31829_RC_RSI80ERAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102522,"speed":24.46,"longitude":-105.0469496},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":92,"serialNumber":15521,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"000000000000032307","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416780373,"long":-1087800160},"name":"westbound_I80_111.16_130.84_SAT-60EFA4BA_RC_RSI80ERAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087818098,"lat":416784087}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}},{"delta":{"node-LatLon":{"lon":-1087907758,"lat":416802744}}},{"delta":{"node-LatLon":{"lon":-1087979504,"lat":416817627}}},{"delta":{"node-LatLon":{"lon":-1088052834,"lat":416835667}}},{"delta":{"node-LatLon":{"lon":-1088118809,"lat":416865925}}},{"delta":{"node-LatLon":{"lon":-1088189118,"lat":416887479}}},{"delta":{"node-LatLon":{"lon":-1088265956,"lat":416884718}}},{"delta":{"node-LatLon":{"lon":-1088342780,"lat":416881687}}},{"delta":{"node-LatLon":{"lon":-1088419492,"lat":416886484}}},{"delta":{"node-LatLon":{"lon":-1088493522,"lat":416903350}}},{"delta":{"node-LatLon":{"lon":-1088567559,"lat":416920405}}},{"delta":{"node-LatLon":{"lon":-1088642038,"lat":416936455}}},{"delta":{"node-LatLon":{"lon":-1088718787,"lat":416933306}}},{"delta":{"node-LatLon":{"lon":-1088792811,"lat":416916445}}},{"delta":{"node-LatLon":{"lon":-1088868743,"lat":416911533}}},{"delta":{"node-LatLon":{"lon":-1088944838,"lat":416921259}}},{"delta":{"node-LatLon":{"lon":-1089020933,"lat":416916370}}},{"delta":{"node-LatLon":{"lon":-1089090262,"lat":416891382}}},{"delta":{"node-LatLon":{"lon":-1089158444,"lat":416862087}}},{"delta":{"node-LatLon":{"lon":-1089206739,"lat":416816167}}},{"delta":{"node-LatLon":{"lon":-1089229701,"lat":416761043}}},{"delta":{"node-LatLon":{"lon":-1089278517,"lat":416719880}}},{"delta":{"node-LatLon":{"lon":-1089348486,"lat":416699184}}},{"delta":{"node-LatLon":{"lon":-1089425832,"lat":416694198}}},{"delta":{"node-LatLon":{"lon":-1089503649,"lat":416693457}}},{"delta":{"node-LatLon":{"lon":-1089580254,"lat":416689749}}},{"delta":{"node-LatLon":{"lon":-1089654935,"lat":416679778}}},{"delta":{"node-LatLon":{"lon":-1089727701,"lat":416664462}}},{"delta":{"node-LatLon":{"lon":-1089800350,"lat":416634151}}},{"delta":{"node-LatLon":{"lon":-1089872661,"lat":416603374}}},{"delta":{"node-LatLon":{"lon":-1089942282,"lat":416573714}}},{"delta":{"node-LatLon":{"lon":-1090009243,"lat":416545210}}},{"delta":{"node-LatLon":{"lon":-1090076173,"lat":416516668}}},{"delta":{"node-LatLon":{"lon":-1090143069,"lat":416488162}}},{"delta":{"node-LatLon":{"lon":-1090209918,"lat":416459596}}},{"delta":{"node-LatLon":{"lon":-1090277470,"lat":416430810}}},{"delta":{"node-LatLon":{"lon":-1090345662,"lat":416401720}}},{"delta":{"node-LatLon":{"lon":-1090413831,"lat":416372606}}},{"delta":{"node-LatLon":{"lon":-1090485302,"lat":416354405}}},{"delta":{"node-LatLon":{"lon":-1090559312,"lat":416342147}}},{"delta":{"node-LatLon":{"lon":-1090633109,"lat":416329839}}},{"delta":{"node-LatLon":{"lon":-1090706742,"lat":416317644}}},{"delta":{"node-LatLon":{"lon":-1090780363,"lat":416305412}}},{"delta":{"node-LatLon":{"lon":-1090854362,"lat":416289159}}},{"delta":{"node-LatLon":{"lon":-1090923703,"lat":416263510}}},{"delta":{"node-LatLon":{"lon":-1090992931,"lat":416237673}}},{"delta":{"node-LatLon":{"lon":-1091062121,"lat":416211766}}},{"delta":{"node-LatLon":{"lon":-1091131370,"lat":416185951}}},{"delta":{"node-LatLon":{"lon":-1091198118,"lat":416160999}}},{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091281511,"lat":416129751}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000011111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416780373,"long":-1087800160}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025176,"speed":24.46,"longitude":-105.0469782},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":91,"serialNumber":15520,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31497,"packetID":"0000000000000BC3EF","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415325796,"long":-1094614954},"name":"westbound_I80_90.098_90.312_SAT-8D4B0B6B_RC_GRTUNWB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094647572,"lat":415340958}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094677547,"lat":415358928}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000000100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415325796,"long":-1094614954}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31497}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025176,"speed":24.46,"longitude":-105.0469782},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":90,"serialNumber":15519,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000A6155","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415272879,"long":-1094524441},"name":"westbound_I80_83.01_91.0_SAT-BCC7F251_RC_RSI80WGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}},{"delta":{"node-LatLon":{"lon":-1094567629,"lat":415301333}}},{"delta":{"node-LatLon":{"lon":-1094598552,"lat":415318326}}},{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}},{"delta":{"node-LatLon":{"lon":-1094725523,"lat":415382855}}},{"delta":{"node-LatLon":{"lon":-1094759103,"lat":415397020}}},{"delta":{"node-LatLon":{"lon":-1094787376,"lat":415416158}}},{"delta":{"node-LatLon":{"lon":-1094803681,"lat":415442345}}},{"delta":{"node-LatLon":{"lon":-1094827523,"lat":415464696}}},{"delta":{"node-LatLon":{"lon":-1094857768,"lat":415483037}}},{"delta":{"node-LatLon":{"lon":-1094888001,"lat":415501390}}},{"delta":{"node-LatLon":{"lon":-1094919170,"lat":415518798}}},{"delta":{"node-LatLon":{"lon":-1094953846,"lat":415531903}}},{"delta":{"node-LatLon":{"lon":-1094991158,"lat":415539943}}},{"delta":{"node-LatLon":{"lon":-1095029104,"lat":415543908}}},{"delta":{"node-LatLon":{"lon":-1095067107,"lat":415547593}}},{"delta":{"node-LatLon":{"lon":-1095105120,"lat":415551220}}},{"delta":{"node-LatLon":{"lon":-1095142989,"lat":415555524}}},{"delta":{"node-LatLon":{"lon":-1095178583,"lat":415565942}}},{"delta":{"node-LatLon":{"lon":-1095212839,"lat":415581431}}},{"delta":{"node-LatLon":{"lon":-1095248825,"lat":415594355}}},{"delta":{"node-LatLon":{"lon":-1095287864,"lat":415600639}}},{"delta":{"node-LatLon":{"lon":-1095327361,"lat":415605311}}},{"delta":{"node-LatLon":{"lon":-1095366831,"lat":415610104}}},{"delta":{"node-LatLon":{"lon":-1095403172,"lat":415618111}}},{"delta":{"node-LatLon":{"lon":-1095437320,"lat":415630465}}},{"delta":{"node-LatLon":{"lon":-1095472268,"lat":415641378}}},{"delta":{"node-LatLon":{"lon":-1095509638,"lat":415645822}}},{"delta":{"node-LatLon":{"lon":-1095547341,"lat":415643461}}},{"delta":{"node-LatLon":{"lon":-1095583235,"lat":415634481}}},{"delta":{"node-LatLon":{"lon":-1095616942,"lat":415621427}}},{"delta":{"node-LatLon":{"lon":-1095650544,"lat":415608220}}},{"delta":{"node-LatLon":{"lon":-1095684389,"lat":415595379}}},{"delta":{"node-LatLon":{"lon":-1095720328,"lat":415586411}}},{"delta":{"node-LatLon":{"lon":-1095758260,"lat":415580697}}},{"delta":{"node-LatLon":{"lon":-1095796228,"lat":415575112}}},{"delta":{"node-LatLon":{"lon":-1095834193,"lat":415569520}}},{"delta":{"node-LatLon":{"lon":-1095872158,"lat":415563926}}},{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415272879,"long":-1094524441}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025133,"speed":24.46,"longitude":-105.0470067},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":89,"serialNumber":15518,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000210A5","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415546021,"long":-1095927626},"name":"eastbound_I80_83.01_91.0_SAT-AEC2BC20_RC_RSI80WGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095910196,"lat":415552425}}},{"delta":{"node-LatLon":{"lon":-1095873554,"lat":415561468}}},{"delta":{"node-LatLon":{"lon":-1095835664,"lat":415567106}}},{"delta":{"node-LatLon":{"lon":-1095797758,"lat":415572690}}},{"delta":{"node-LatLon":{"lon":-1095759854,"lat":415578281}}},{"delta":{"node-LatLon":{"lon":-1095721965,"lat":415583926}}},{"delta":{"node-LatLon":{"lon":-1095685445,"lat":415592676}}},{"delta":{"node-LatLon":{"lon":-1095651117,"lat":415605559}}},{"delta":{"node-LatLon":{"lon":-1095617101,"lat":415618922}}},{"delta":{"node-LatLon":{"lon":-1095583008,"lat":415632176}}},{"delta":{"node-LatLon":{"lon":-1095546731,"lat":415641373}}},{"delta":{"node-LatLon":{"lon":-1095509731,"lat":415643672}}},{"delta":{"node-LatLon":{"lon":-1095473059,"lat":415639326}}},{"delta":{"node-LatLon":{"lon":-1095438752,"lat":415628644}}},{"delta":{"node-LatLon":{"lon":-1095405325,"lat":415616388}}},{"delta":{"node-LatLon":{"lon":-1095369730,"lat":415608358}}},{"delta":{"node-LatLon":{"lon":-1095330616,"lat":415603528}}},{"delta":{"node-LatLon":{"lon":-1095291457,"lat":415598888}}},{"delta":{"node-LatLon":{"lon":-1095252639,"lat":415593016}}},{"delta":{"node-LatLon":{"lon":-1095216703,"lat":415580638}}},{"delta":{"node-LatLon":{"lon":-1095182775,"lat":415565235}}},{"delta":{"node-LatLon":{"lon":-1095147149,"lat":415554096}}},{"delta":{"node-LatLon":{"lon":-1095108985,"lat":415549420}}},{"delta":{"node-LatLon":{"lon":-1095070589,"lat":415545729}}},{"delta":{"node-LatLon":{"lon":-1095032188,"lat":415542064}}},{"delta":{"node-LatLon":{"lon":-1094993831,"lat":415538174}}},{"delta":{"node-LatLon":{"lon":-1094956860,"lat":415530480}}},{"delta":{"node-LatLon":{"lon":-1094922411,"lat":415517802}}},{"delta":{"node-LatLon":{"lon":-1094891469,"lat":415500743}}},{"delta":{"node-LatLon":{"lon":-1094861594,"lat":415482600}}},{"delta":{"node-LatLon":{"lon":-1094831707,"lat":415464468}}},{"delta":{"node-LatLon":{"lon":-1094806972,"lat":415442662}}},{"delta":{"node-LatLon":{"lon":-1094790913,"lat":415416378}}},{"delta":{"node-LatLon":{"lon":-1094763585,"lat":415396461}}},{"delta":{"node-LatLon":{"lon":-1094730035,"lat":415382264}}},{"delta":{"node-LatLon":{"lon":-1094697171,"lat":415367224}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}},{"delta":{"node-LatLon":{"lon":-1094603326,"lat":415317623}}},{"delta":{"node-LatLon":{"lon":-1094571921,"lat":415301218}}},{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415546021,"long":-1095927626}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025088,"speed":24.46,"longitude":-105.0470353},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":88,"serialNumber":15517,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025046,"speed":24.46,"longitude":-105.0470638},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":87,"serialNumber":15516,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31495,"packetID":"00000000000008F38B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416142272,"long":-1091248169},"name":"westbound_I80_104.83_111.16_SAT-F2240036_RC_RSI80MARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091298228,"lat":416123561}}},{"delta":{"node-LatLon":{"lon":-1091334018,"lat":416110189}}},{"delta":{"node-LatLon":{"lon":-1091369795,"lat":416096798}}},{"delta":{"node-LatLon":{"lon":-1091405563,"lat":416083396}}},{"delta":{"node-LatLon":{"lon":-1091441283,"lat":416069923}}},{"delta":{"node-LatLon":{"lon":-1091474700,"lat":416053537}}},{"delta":{"node-LatLon":{"lon":-1091501964,"lat":416033828}}},{"delta":{"node-LatLon":{"lon":-1091526844,"lat":416012368}}},{"delta":{"node-LatLon":{"lon":-1091552241,"lat":415991270}}},{"delta":{"node-LatLon":{"lon":-1091583184,"lat":415974991}}},{"delta":{"node-LatLon":{"lon":-1091618832,"lat":415965599}}},{"delta":{"node-LatLon":{"lon":-1091657262,"lat":415963124}}},{"delta":{"node-LatLon":{"lon":-1091695868,"lat":415962098}}},{"delta":{"node-LatLon":{"lon":-1091734473,"lat":415961055}}},{"delta":{"node-LatLon":{"lon":-1091772519,"lat":415956756}}},{"delta":{"node-LatLon":{"lon":-1091806953,"lat":415943769}}},{"delta":{"node-LatLon":{"lon":-1091836882,"lat":415930461}}},{"delta":{"node-LatLon":{"lon":-1091869287,"lat":415921267}}},{"delta":{"node-LatLon":{"lon":-1091903898,"lat":415920097}}},{"delta":{"node-LatLon":{"lon":-1091937392,"lat":415926747}}},{"delta":{"node-LatLon":{"lon":-1091966574,"lat":415940771}}},{"delta":{"node-LatLon":{"lon":-1091990723,"lat":415963402}}},{"delta":{"node-LatLon":{"lon":-1092004823,"lat":415990502}}},{"delta":{"node-LatLon":{"lon":-1092019104,"lat":416017543}}},{"delta":{"node-LatLon":{"lon":-1092043521,"lat":416040022}}},{"delta":{"node-LatLon":{"lon":-1092074899,"lat":416057166}}},{"delta":{"node-LatLon":{"lon":-1092100017,"lat":416070268}}},{"delta":{"node-LatLon":{"lon":-1092125100,"lat":416083407}}},{"delta":{"node-LatLon":{"lon":-1092151035,"lat":416095519}}},{"delta":{"node-LatLon":{"lon":-1092180024,"lat":416102624}}},{"delta":{"node-LatLon":{"lon":-1092210485,"lat":416103734}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416142272,"long":-1091248169}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31495}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025046,"speed":24.46,"longitude":-105.0470638},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":86,"serialNumber":15515,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025002,"speed":24.46,"longitude":-105.0470924},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":85,"serialNumber":15514,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31490,"packetID":"0000000000000A5426","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416070648,"long":-1092309469},"name":"eastbound_I80_104.83_111.16_SAT-5D20AE10_RC_RSI80MARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092256961,"lat":416090938}}},{"delta":{"node-LatLon":{"lon":-1092220011,"lat":416100743}}},{"delta":{"node-LatLon":{"lon":-1092180837,"lat":416100613}}},{"delta":{"node-LatLon":{"lon":-1092144100,"lat":416090411}}},{"delta":{"node-LatLon":{"lon":-1092111577,"lat":416073768}}},{"delta":{"node-LatLon":{"lon":-1092079251,"lat":416056897}}},{"delta":{"node-LatLon":{"lon":-1092047614,"lat":416039914}}},{"delta":{"node-LatLon":{"lon":-1092022496,"lat":416017802}}},{"delta":{"node-LatLon":{"lon":-1092007875,"lat":415990813}}},{"delta":{"node-LatLon":{"lon":-1091994030,"lat":415963562}}},{"delta":{"node-LatLon":{"lon":-1091970384,"lat":415940547}}},{"delta":{"node-LatLon":{"lon":-1091941029,"lat":415925731}}},{"delta":{"node-LatLon":{"lon":-1091907083,"lat":415918255}}},{"delta":{"node-LatLon":{"lon":-1091871710,"lat":415918755}}},{"delta":{"node-LatLon":{"lon":-1091838259,"lat":415927373}}},{"delta":{"node-LatLon":{"lon":-1091807633,"lat":415940869}}},{"delta":{"node-LatLon":{"lon":-1091773693,"lat":415954295}}},{"delta":{"node-LatLon":{"lon":-1091735915,"lat":415958860}}},{"delta":{"node-LatLon":{"lon":-1091697507,"lat":415959950}}},{"delta":{"node-LatLon":{"lon":-1091659097,"lat":415960991}}},{"delta":{"node-LatLon":{"lon":-1091620811,"lat":415963173}}},{"delta":{"node-LatLon":{"lon":-1091584800,"lat":415972056}}},{"delta":{"node-LatLon":{"lon":-1091553176,"lat":415987749}}},{"delta":{"node-LatLon":{"lon":-1091527289,"lat":416008625}}},{"delta":{"node-LatLon":{"lon":-1091502330,"lat":416030163}}},{"delta":{"node-LatLon":{"lon":-1091474365,"lat":416049452}}},{"delta":{"node-LatLon":{"lon":-1091440655,"lat":416065279}}},{"delta":{"node-LatLon":{"lon":-1091405002,"lat":416078597}}},{"delta":{"node-LatLon":{"lon":-1091369361,"lat":416091933}}},{"delta":{"node-LatLon":{"lon":-1091333716,"lat":416105264}}},{"delta":{"node-LatLon":{"lon":-1091298057,"lat":416118575}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416070648,"long":-1092309469}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31490}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024958,"speed":24.46,"longitude":-105.0471209},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":84,"serialNumber":15513,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"000000000000073298","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411170053,"long":-1048682540},"name":"westbound_I80_348.36_358.5_SAT-C5FF6D31_RC_CHEYI80WLARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048702211,"lat":411170073}}},{"delta":{"node-LatLon":{"lon":-1048721881,"lat":411170051}}},{"delta":{"node-LatLon":{"lon":-1048761222,"lat":411169874}}},{"delta":{"node-LatLon":{"lon":-1048800563,"lat":411169714}}},{"delta":{"node-LatLon":{"lon":-1048839240,"lat":411169551}}},{"delta":{"node-LatLon":{"lon":-1048877917,"lat":411169445}}},{"delta":{"node-LatLon":{"lon":-1048916593,"lat":411169353}}},{"delta":{"node-LatLon":{"lon":-1048955270,"lat":411169236}}},{"delta":{"node-LatLon":{"lon":-1048993946,"lat":411169016}}},{"delta":{"node-LatLon":{"lon":-1049032247,"lat":411168874}}},{"delta":{"node-LatLon":{"lon":-1049070527,"lat":411168170}}},{"delta":{"node-LatLon":{"lon":-1049108247,"lat":411163290}}},{"delta":{"node-LatLon":{"lon":-1049145661,"lat":411157085}}},{"delta":{"node-LatLon":{"lon":-1049183059,"lat":411150832}}},{"delta":{"node-LatLon":{"lon":-1049220325,"lat":411144893}}},{"delta":{"node-LatLon":{"lon":-1049257999,"lat":411140682}}},{"delta":{"node-LatLon":{"lon":-1049295723,"lat":411136728}}},{"delta":{"node-LatLon":{"lon":-1049333444,"lat":411132751}}},{"delta":{"node-LatLon":{"lon":-1049371183,"lat":411128874}}},{"delta":{"node-LatLon":{"lon":-1049409390,"lat":411124909}}},{"delta":{"node-LatLon":{"lon":-1049447598,"lat":411120949}}},{"delta":{"node-LatLon":{"lon":-1049485797,"lat":411116940}}},{"delta":{"node-LatLon":{"lon":-1049524006,"lat":411112988}}},{"delta":{"node-LatLon":{"lon":-1049562308,"lat":411109647}}},{"delta":{"node-LatLon":{"lon":-1049600401,"lat":411107207}}},{"delta":{"node-LatLon":{"lon":-1049638492,"lat":411104750}}},{"delta":{"node-LatLon":{"lon":-1049676581,"lat":411102282}}},{"delta":{"node-LatLon":{"lon":-1049714466,"lat":411098457}}},{"delta":{"node-LatLon":{"lon":-1049752216,"lat":411093893}}},{"delta":{"node-LatLon":{"lon":-1049790068,"lat":411089292}}},{"delta":{"node-LatLon":{"lon":-1049827923,"lat":411084707}}},{"delta":{"node-LatLon":{"lon":-1049865779,"lat":411080125}}},{"delta":{"node-LatLon":{"lon":-1049903602,"lat":411075397}}},{"delta":{"node-LatLon":{"lon":-1049940392,"lat":411067384}}},{"delta":{"node-LatLon":{"lon":-1049976102,"lat":411057362}}},{"delta":{"node-LatLon":{"lon":-1050011796,"lat":411047308}}},{"delta":{"node-LatLon":{"lon":-1050047479,"lat":411037232}}},{"delta":{"node-LatLon":{"lon":-1050083173,"lat":411027181}}},{"delta":{"node-LatLon":{"lon":-1050119263,"lat":411018037}}},{"delta":{"node-LatLon":{"lon":-1050156120,"lat":411013697}}},{"delta":{"node-LatLon":{"lon":-1050193406,"lat":411014492}}},{"delta":{"node-LatLon":{"lon":-1050230066,"lat":411019821}}},{"delta":{"node-LatLon":{"lon":-1050266545,"lat":411025893}}},{"delta":{"node-LatLon":{"lon":-1050303026,"lat":411031959}}},{"delta":{"node-LatLon":{"lon":-1050341801,"lat":411036364}}},{"delta":{"node-LatLon":{"lon":-1050381045,"lat":411036216}}},{"delta":{"node-LatLon":{"lon":-1050420282,"lat":411035204}}},{"delta":{"node-LatLon":{"lon":-1050459188,"lat":411031556}}},{"delta":{"node-LatLon":{"lon":-1050497693,"lat":411025753}}},{"delta":{"node-LatLon":{"lon":-1050534808,"lat":411020098}}},{"delta":{"node-LatLon":{"lon":-1050571919,"lat":411014428}}},{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050627605,"lat":411006003}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411170053,"long":-1048682540}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024958,"speed":24.46,"longitude":-105.0471209},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":83,"serialNumber":15512,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"0000000000000B9403","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410998545,"long":-1050648246},"name":"eastbound_I80_348.36_358.5_SAT-D8707F73_RC_CHEYI80WLARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}},{"delta":{"node-LatLon":{"lon":-1050422091,"lat":411030485}}},{"delta":{"node-LatLon":{"lon":-1050383473,"lat":411031428}}},{"delta":{"node-LatLon":{"lon":-1050344848,"lat":411031826}}},{"delta":{"node-LatLon":{"lon":-1050306653,"lat":411027659}}},{"delta":{"node-LatLon":{"lon":-1050269678,"lat":411021507}}},{"delta":{"node-LatLon":{"lon":-1050232676,"lat":411015448}}},{"delta":{"node-LatLon":{"lon":-1050195535,"lat":411009957}}},{"delta":{"node-LatLon":{"lon":-1050157751,"lat":411008904}}},{"delta":{"node-LatLon":{"lon":-1050120335,"lat":411013008}}},{"delta":{"node-LatLon":{"lon":-1050084082,"lat":411021875}}},{"delta":{"node-LatLon":{"lon":-1050048325,"lat":411031899}}},{"delta":{"node-LatLon":{"lon":-1050012604,"lat":411041995}}},{"delta":{"node-LatLon":{"lon":-1049976865,"lat":411052057}}},{"delta":{"node-LatLon":{"lon":-1049941141,"lat":411062151}}},{"delta":{"node-LatLon":{"lon":-1049904488,"lat":411070470}}},{"delta":{"node-LatLon":{"lon":-1049866692,"lat":411075206}}},{"delta":{"node-LatLon":{"lon":-1049828870,"lat":411079830}}},{"delta":{"node-LatLon":{"lon":-1049791039,"lat":411084415}}},{"delta":{"node-LatLon":{"lon":-1049753209,"lat":411089002}}},{"delta":{"node-LatLon":{"lon":-1049715382,"lat":411093589}}},{"delta":{"node-LatLon":{"lon":-1049677431,"lat":411097499}}},{"delta":{"node-LatLon":{"lon":-1049639263,"lat":411099987}}},{"delta":{"node-LatLon":{"lon":-1049601097,"lat":411102498}}},{"delta":{"node-LatLon":{"lon":-1049562935,"lat":411105044}}},{"delta":{"node-LatLon":{"lon":-1049524970,"lat":411108146}}},{"delta":{"node-LatLon":{"lon":-1049487125,"lat":411112044}}},{"delta":{"node-LatLon":{"lon":-1049449291,"lat":411116003}}},{"delta":{"node-LatLon":{"lon":-1049411457,"lat":411119968}}},{"delta":{"node-LatLon":{"lon":-1049373623,"lat":411123930}}},{"delta":{"node-LatLon":{"lon":-1049335535,"lat":411127975}}},{"delta":{"node-LatLon":{"lon":-1049297422,"lat":411131886}}},{"delta":{"node-LatLon":{"lon":-1049259309,"lat":411135796}}},{"delta":{"node-LatLon":{"lon":-1049221247,"lat":411139978}}},{"delta":{"node-LatLon":{"lon":-1049183591,"lat":411145899}}},{"delta":{"node-LatLon":{"lon":-1049146455,"lat":411152154}}},{"delta":{"node-LatLon":{"lon":-1049109301,"lat":411158352}}},{"delta":{"node-LatLon":{"lon":-1049071864,"lat":411163355}}},{"delta":{"node-LatLon":{"lon":-1049033848,"lat":411164138}}},{"delta":{"node-LatLon":{"lon":-1048995803,"lat":411164285}}},{"delta":{"node-LatLon":{"lon":-1048957165,"lat":411164452}}},{"delta":{"node-LatLon":{"lon":-1048918528,"lat":411164604}}},{"delta":{"node-LatLon":{"lon":-1048879891,"lat":411164841}}},{"delta":{"node-LatLon":{"lon":-1048841254,"lat":411165037}}},{"delta":{"node-LatLon":{"lon":-1048802617,"lat":411165193}}},{"delta":{"node-LatLon":{"lon":-1048763807,"lat":411165332}}},{"delta":{"node-LatLon":{"lon":-1048724997,"lat":411165480}}},{"delta":{"node-LatLon":{"lon":-1048705592,"lat":411165575}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410998545,"long":-1050648246}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024915,"speed":24.46,"longitude":-105.0471495},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":82,"serialNumber":15511,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"000000000000087964","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411011592,"long":-1050590473},"name":"westbound_I80_335.11_348.36_SAT-4982596C_RC_CHEYI80WHARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050684029,"lat":411002155}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411011592,"long":-1050590473}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024871,"speed":24.46,"longitude":-105.047178},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":81,"serialNumber":15510,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"0000000000000A3B4E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-6CD34EF8_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024871,"speed":24.46,"longitude":-105.047178},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":80,"serialNumber":15509,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31276,"packetID":"0000000000000C7BDC","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411583071,"long":-1045194573},"name":"westbound_I80_370.1_377.35_SAT-1F3353B9_RC_CHEYI80EPBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045213731,"lat":411583474}}},{"delta":{"node-LatLon":{"lon":-1045252048,"lat":411584277}}},{"delta":{"node-LatLon":{"lon":-1045290377,"lat":411584588}}},{"delta":{"node-LatLon":{"lon":-1045329055,"lat":411584606}}},{"delta":{"node-LatLon":{"lon":-1045367733,"lat":411584612}}},{"delta":{"node-LatLon":{"lon":-1045406412,"lat":411584626}}},{"delta":{"node-LatLon":{"lon":-1045445090,"lat":411584615}}},{"delta":{"node-LatLon":{"lon":-1045483768,"lat":411584618}}},{"delta":{"node-LatLon":{"lon":-1045521914,"lat":411584627}}},{"delta":{"node-LatLon":{"lon":-1045560059,"lat":411584625}}},{"delta":{"node-LatLon":{"lon":-1045598205,"lat":411584639}}},{"delta":{"node-LatLon":{"lon":-1045636350,"lat":411584589}}},{"delta":{"node-LatLon":{"lon":-1045674495,"lat":411584576}}},{"delta":{"node-LatLon":{"lon":-1045712807,"lat":411584579}}},{"delta":{"node-LatLon":{"lon":-1045751120,"lat":411584598}}},{"delta":{"node-LatLon":{"lon":-1045789432,"lat":411584756}}},{"delta":{"node-LatLon":{"lon":-1045827743,"lat":411584908}}},{"delta":{"node-LatLon":{"lon":-1045866056,"lat":411585030}}},{"delta":{"node-LatLon":{"lon":-1045904386,"lat":411585214}}},{"delta":{"node-LatLon":{"lon":-1045942717,"lat":411585361}}},{"delta":{"node-LatLon":{"lon":-1045981047,"lat":411585545}}},{"delta":{"node-LatLon":{"lon":-1046019378,"lat":411585693}}},{"delta":{"node-LatLon":{"lon":-1046057708,"lat":411585870}}},{"delta":{"node-LatLon":{"lon":-1046096147,"lat":411586011}}},{"delta":{"node-LatLon":{"lon":-1046134585,"lat":411586177}}},{"delta":{"node-LatLon":{"lon":-1046173023,"lat":411586326}}},{"delta":{"node-LatLon":{"lon":-1046211460,"lat":411586584}}},{"delta":{"node-LatLon":{"lon":-1046249897,"lat":411586868}}},{"delta":{"node-LatLon":{"lon":-1046288331,"lat":411587218}}},{"delta":{"node-LatLon":{"lon":-1046326766,"lat":411587517}}},{"delta":{"node-LatLon":{"lon":-1046365200,"lat":411587809}}},{"delta":{"node-LatLon":{"lon":-1046403636,"lat":411588036}}},{"delta":{"node-LatLon":{"lon":-1046442034,"lat":411586845}}},{"delta":{"node-LatLon":{"lon":-1046479971,"lat":411583989}}},{"delta":{"node-LatLon":{"lon":-1046517601,"lat":411579361}}},{"delta":{"node-LatLon":{"lon":-1046554803,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1046591419,"lat":411565023}}},{"delta":{"node-LatLon":{"lon":-1046609462,"lat":411560366}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411583071,"long":-1045194573}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31276}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024828,"speed":24.46,"longitude":-105.0472065},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":79,"serialNumber":15508,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31276,"packetID":"00000000000005CEB8","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411550674,"long":-1046626808},"name":"eastbound_I80_370.1_377.35_SAT-D4C24D15_RC_CHEYI80EPBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046609118,"lat":411555717}}},{"delta":{"node-LatLon":{"lon":-1046591249,"lat":411560386}}},{"delta":{"node-LatLon":{"lon":-1046554972,"lat":411568439}}},{"delta":{"node-LatLon":{"lon":-1046518106,"lat":411574777}}},{"delta":{"node-LatLon":{"lon":-1046480798,"lat":411579409}}},{"delta":{"node-LatLon":{"lon":-1046443186,"lat":411582321}}},{"delta":{"node-LatLon":{"lon":-1046405109,"lat":411583506}}},{"delta":{"node-LatLon":{"lon":-1046366997,"lat":411583305}}},{"delta":{"node-LatLon":{"lon":-1046328885,"lat":411583053}}},{"delta":{"node-LatLon":{"lon":-1046290773,"lat":411582732}}},{"delta":{"node-LatLon":{"lon":-1046252662,"lat":411582431}}},{"delta":{"node-LatLon":{"lon":-1046213997,"lat":411582141}}},{"delta":{"node-LatLon":{"lon":-1046175333,"lat":411581845}}},{"delta":{"node-LatLon":{"lon":-1046136667,"lat":411581682}}},{"delta":{"node-LatLon":{"lon":-1046098002,"lat":411581519}}},{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}},{"delta":{"node-LatLon":{"lon":-1045638356,"lat":411580096}}},{"delta":{"node-LatLon":{"lon":-1045599910,"lat":411580126}}},{"delta":{"node-LatLon":{"lon":-1045561463,"lat":411580111}}},{"delta":{"node-LatLon":{"lon":-1045523016,"lat":411580105}}},{"delta":{"node-LatLon":{"lon":-1045484569,"lat":411580102}}},{"delta":{"node-LatLon":{"lon":-1045446114,"lat":411580096}}},{"delta":{"node-LatLon":{"lon":-1045407659,"lat":411580116}}},{"delta":{"node-LatLon":{"lon":-1045369203,"lat":411580107}}},{"delta":{"node-LatLon":{"lon":-1045330748,"lat":411580102}}},{"delta":{"node-LatLon":{"lon":-1045292292,"lat":411580094}}},{"delta":{"node-LatLon":{"lon":-1045253937,"lat":411579790}}},{"delta":{"node-LatLon":{"lon":-1045215592,"lat":411579032}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411550674,"long":-1046626808}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31276}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024828,"speed":24.46,"longitude":-105.0472065},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":78,"serialNumber":15507,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31484,"packetID":"0000000000000687E2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411011592,"long":-1050590473},"name":"westbound_I80_335.11_348.36_SAT-592E2A83_RC_CHEYI80WHARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050684029,"lat":411002155}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411011592,"long":-1050590473}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31484}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024784,"speed":24.46,"longitude":-105.0472351},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":76,"serialNumber":15505,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31483,"packetID":"0000000000000B4F4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411246688,"long":-1053019776},"name":"westbound_I80_323.05_335.11_SAT-B91A2E52_RC_LARI80ECHEYBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054127454,"lat":411694572}}},{"delta":{"node-LatLon":{"lon":-1054164403,"lat":411745737}}},{"delta":{"node-LatLon":{"lon":-1054200041,"lat":411796105}}},{"delta":{"node-LatLon":{"lon":-1054218886,"lat":411851211}}},{"delta":{"node-LatLon":{"lon":-1054243815,"lat":411905185}}},{"delta":{"node-LatLon":{"lon":-1054287780,"lat":411952905}}},{"delta":{"node-LatLon":{"lon":-1054331852,"lat":412000578}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000001111}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411246688,"long":-1053019776}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":4868}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31483}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024784,"speed":24.46,"longitude":-105.0472351},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":77,"serialNumber":15506,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31484,"packetID":"00000000000004AA70","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-9AFEBCD7_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31484}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024741,"speed":24.46,"longitude":-105.0472635},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":75,"serialNumber":15504,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31483,"packetID":"0000000000000F25D6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412420501,"long":-1054392109},"name":"eastbound_I80_323.05_335.11_SAT-2FAB6C57_RC_LARI80ECHEYBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111110000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412420501,"long":-1054392109}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":4868}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31483}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024697,"speed":24.46,"longitude":-105.0472922},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":74,"serialNumber":15503,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000992DB","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412969911,"long":-1055922054},"name":"westbound_I80_290.44_313.19_SAT-39E13EDB_RC_LARI80WQDHLD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055939598,"lat":412974628}}},{"delta":{"node-LatLon":{"lon":-1056011013,"lat":412993846}}},{"delta":{"node-LatLon":{"lon":-1056083564,"lat":413013351}}},{"delta":{"node-LatLon":{"lon":-1056136131,"lat":413051965}}},{"delta":{"node-LatLon":{"lon":-1056142604,"lat":413111070}}},{"delta":{"node-LatLon":{"lon":-1056147739,"lat":413170299}}},{"delta":{"node-LatLon":{"lon":-1056152707,"lat":413227440}}},{"delta":{"node-LatLon":{"lon":-1056157480,"lat":413282495}}},{"delta":{"node-LatLon":{"lon":-1056162332,"lat":413337546}}},{"delta":{"node-LatLon":{"lon":-1056179338,"lat":413394642}}},{"delta":{"node-LatLon":{"lon":-1056241841,"lat":413429971}}},{"delta":{"node-LatLon":{"lon":-1056308986,"lat":413460456}}},{"delta":{"node-LatLon":{"lon":-1056375806,"lat":413490715}}},{"delta":{"node-LatLon":{"lon":-1056448549,"lat":413509883}}},{"delta":{"node-LatLon":{"lon":-1056524673,"lat":413510070}}},{"delta":{"node-LatLon":{"lon":-1056600806,"lat":413509928}}},{"delta":{"node-LatLon":{"lon":-1056677878,"lat":413509777}}},{"delta":{"node-LatLon":{"lon":-1056755890,"lat":413509624}}},{"delta":{"node-LatLon":{"lon":-1056833901,"lat":413509486}}},{"delta":{"node-LatLon":{"lon":-1056911534,"lat":413509321}}},{"delta":{"node-LatLon":{"lon":-1056988345,"lat":413503756}}},{"delta":{"node-LatLon":{"lon":-1057063632,"lat":413496157}}},{"delta":{"node-LatLon":{"lon":-1057138866,"lat":413506949}}},{"delta":{"node-LatLon":{"lon":-1057214104,"lat":413517735}}},{"delta":{"node-LatLon":{"lon":-1057289680,"lat":413528551}}},{"delta":{"node-LatLon":{"lon":-1057365257,"lat":413539367}}},{"delta":{"node-LatLon":{"lon":-1057440379,"lat":413550309}}},{"delta":{"node-LatLon":{"lon":-1057512568,"lat":413568354}}},{"delta":{"node-LatLon":{"lon":-1057584309,"lat":413587502}}},{"delta":{"node-LatLon":{"lon":-1057657989,"lat":413607176}}},{"delta":{"node-LatLon":{"lon":-1057731667,"lat":413626859}}},{"delta":{"node-LatLon":{"lon":-1057799444,"lat":413654138}}},{"delta":{"node-LatLon":{"lon":-1057862738,"lat":413685955}}},{"delta":{"node-LatLon":{"lon":-1057926032,"lat":413717776}}},{"delta":{"node-LatLon":{"lon":-1057990466,"lat":413750126}}},{"delta":{"node-LatLon":{"lon":-1058054871,"lat":413782512}}},{"delta":{"node-LatLon":{"lon":-1058117509,"lat":413815643}}},{"delta":{"node-LatLon":{"lon":-1058164753,"lat":413859952}}},{"delta":{"node-LatLon":{"lon":-1058205339,"lat":413908152}}},{"delta":{"node-LatLon":{"lon":-1058246686,"lat":413957163}}},{"delta":{"node-LatLon":{"lon":-1058288005,"lat":414006188}}},{"delta":{"node-LatLon":{"lon":-1058329488,"lat":414055451}}},{"delta":{"node-LatLon":{"lon":-1058376904,"lat":414101638}}},{"delta":{"node-LatLon":{"lon":-1058441692,"lat":414133752}}},{"delta":{"node-LatLon":{"lon":-1058509642,"lat":414161765}}},{"delta":{"node-LatLon":{"lon":-1058577606,"lat":414189762}}},{"delta":{"node-LatLon":{"lon":-1058645229,"lat":414217630}}},{"delta":{"node-LatLon":{"lon":-1058712523,"lat":414245352}}},{"delta":{"node-LatLon":{"lon":-1058779847,"lat":414273037}}},{"delta":{"node-LatLon":{"lon":-1058847466,"lat":414300930}}},{"delta":{"node-LatLon":{"lon":-1058915586,"lat":414328088}}},{"delta":{"node-LatLon":{"lon":-1058989523,"lat":414342520}}},{"delta":{"node-LatLon":{"lon":-1059064093,"lat":414353551}}},{"delta":{"node-LatLon":{"lon":-1059138674,"lat":414364546}}},{"delta":{"node-LatLon":{"lon":-1059214026,"lat":414375694}}},{"delta":{"node-LatLon":{"lon":-1059289381,"lat":414386834}}},{"delta":{"node-LatLon":{"lon":-1059363802,"lat":414397824}}},{"delta":{"node-LatLon":{"lon":-1059437301,"lat":414408619}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412969911,"long":-1055922054}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024697,"speed":24.46,"longitude":-105.0472922},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":73,"serialNumber":15502,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000A5948","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-864EB729_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024653,"speed":24.46,"longitude":-105.0473207},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":72,"serialNumber":15501,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000F8642","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414403179,"long":-1059400563},"name":"westbound_I80_279.86_290.44_SAT-D62DB515_RC_LARI80WRAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059418929,"lat":414405912}}},{"delta":{"node-LatLon":{"lon":-1059437301,"lat":414408619}}},{"delta":{"node-LatLon":{"lon":-1059474045,"lat":414414043}}},{"delta":{"node-LatLon":{"lon":-1059510782,"lat":414419489}}},{"delta":{"node-LatLon":{"lon":-1059549177,"lat":414426609}}},{"delta":{"node-LatLon":{"lon":-1059587159,"lat":414434951}}},{"delta":{"node-LatLon":{"lon":-1059624866,"lat":414443931}}},{"delta":{"node-LatLon":{"lon":-1059658797,"lat":414459046}}},{"delta":{"node-LatLon":{"lon":-1059685629,"lat":414480816}}},{"delta":{"node-LatLon":{"lon":-1059708612,"lat":414504233}}},{"delta":{"node-LatLon":{"lon":-1059731631,"lat":414527631}}},{"delta":{"node-LatLon":{"lon":-1059754662,"lat":414551022}}},{"delta":{"node-LatLon":{"lon":-1059777663,"lat":414574431}}},{"delta":{"node-LatLon":{"lon":-1059800605,"lat":414597873}}},{"delta":{"node-LatLon":{"lon":-1059825019,"lat":414620504}}},{"delta":{"node-LatLon":{"lon":-1059854975,"lat":414638959}}},{"delta":{"node-LatLon":{"lon":-1059886652,"lat":414655790}}},{"delta":{"node-LatLon":{"lon":-1059918347,"lat":414672602}}},{"delta":{"node-LatLon":{"lon":-1059950027,"lat":414689430}}},{"delta":{"node-LatLon":{"lon":-1059981533,"lat":414706207}}},{"delta":{"node-LatLon":{"lon":-1060013094,"lat":414722925}}},{"delta":{"node-LatLon":{"lon":-1060044644,"lat":414739656}}},{"delta":{"node-LatLon":{"lon":-1060076151,"lat":414756434}}},{"delta":{"node-LatLon":{"lon":-1060107672,"lat":414773199}}},{"delta":{"node-LatLon":{"lon":-1060138668,"lat":414789614}}},{"delta":{"node-LatLon":{"lon":-1060169596,"lat":414806103}}},{"delta":{"node-LatLon":{"lon":-1060200600,"lat":414822512}}},{"delta":{"node-LatLon":{"lon":-1060231565,"lat":414838964}}},{"delta":{"node-LatLon":{"lon":-1060262552,"lat":414855394}}},{"delta":{"node-LatLon":{"lon":-1060294303,"lat":414872314}}},{"delta":{"node-LatLon":{"lon":-1060326101,"lat":414889184}}},{"delta":{"node-LatLon":{"lon":-1060357880,"lat":414906076}}},{"delta":{"node-LatLon":{"lon":-1060389415,"lat":414923223}}},{"delta":{"node-LatLon":{"lon":-1060420573,"lat":414940760}}},{"delta":{"node-LatLon":{"lon":-1060450509,"lat":414958838}}},{"delta":{"node-LatLon":{"lon":-1060475868,"lat":414980491}}},{"delta":{"node-LatLon":{"lon":-1060495507,"lat":415005280}}},{"delta":{"node-LatLon":{"lon":-1060510699,"lat":415031818}}},{"delta":{"node-LatLon":{"lon":-1060524843,"lat":415058673}}},{"delta":{"node-LatLon":{"lon":-1060533417,"lat":415086879}}},{"delta":{"node-LatLon":{"lon":-1060540264,"lat":415115378}}},{"delta":{"node-LatLon":{"lon":-1060547197,"lat":415143865}}},{"delta":{"node-LatLon":{"lon":-1060554077,"lat":415172359}}},{"delta":{"node-LatLon":{"lon":-1060561492,"lat":415200772}}},{"delta":{"node-LatLon":{"lon":-1060576552,"lat":415227429}}},{"delta":{"node-LatLon":{"lon":-1060600749,"lat":415249961}}},{"delta":{"node-LatLon":{"lon":-1060632200,"lat":415266697}}},{"delta":{"node-LatLon":{"lon":-1060666183,"lat":415280527}}},{"delta":{"node-LatLon":{"lon":-1060695463,"lat":415299353}}},{"delta":{"node-LatLon":{"lon":-1060719162,"lat":415322019}}},{"delta":{"node-LatLon":{"lon":-1060742498,"lat":415344904}}},{"delta":{"node-LatLon":{"lon":-1060765869,"lat":415367768}}},{"delta":{"node-LatLon":{"lon":-1060789259,"lat":415390622}}},{"delta":{"node-LatLon":{"lon":-1060812632,"lat":415413487}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414403179,"long":-1059400563}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102461,"speed":24.46,"longitude":-105.0473492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":70,"serialNumber":15499,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31288,"packetID":"00000000000007A7DE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417284807,"long":-1077291383},"name":"westbound_I80_173.41_187.2_SAT-2205BAF6_RC_WAMI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1077310157,"lat":417280493}}},{"delta":{"node-LatLon":{"lon":-1077365582,"lat":417267865}}},{"delta":{"node-LatLon":{"lon":-1077438858,"lat":417251174}}},{"delta":{"node-LatLon":{"lon":-1077512126,"lat":417234471}}},{"delta":{"node-LatLon":{"lon":-1077586147,"lat":417217588}}},{"delta":{"node-LatLon":{"lon":-1077660175,"lat":417200729}}},{"delta":{"node-LatLon":{"lon":-1077734162,"lat":417183833}}},{"delta":{"node-LatLon":{"lon":-1077808136,"lat":417166974}}},{"delta":{"node-LatLon":{"lon":-1077882091,"lat":417150070}}},{"delta":{"node-LatLon":{"lon":-1077955526,"lat":417133360}}},{"delta":{"node-LatLon":{"lon":-1078028926,"lat":417116571}}},{"delta":{"node-LatLon":{"lon":-1078102836,"lat":417099694}}},{"delta":{"node-LatLon":{"lon":-1078177231,"lat":417082670}}},{"delta":{"node-LatLon":{"lon":-1078251628,"lat":417065655}}},{"delta":{"node-LatLon":{"lon":-1078327521,"lat":417053313}}},{"delta":{"node-LatLon":{"lon":-1078405145,"lat":417051623}}},{"delta":{"node-LatLon":{"lon":-1078479666,"lat":417055725}}},{"delta":{"node-LatLon":{"lon":-1078551136,"lat":417059767}}},{"delta":{"node-LatLon":{"lon":-1078622626,"lat":417063607}}},{"delta":{"node-LatLon":{"lon":-1078700426,"lat":417063986}}},{"delta":{"node-LatLon":{"lon":-1078778089,"lat":417060211}}},{"delta":{"node-LatLon":{"lon":-1078855705,"lat":417056048}}},{"delta":{"node-LatLon":{"lon":-1078933113,"lat":417050466}}},{"delta":{"node-LatLon":{"lon":-1079008244,"lat":417035644}}},{"delta":{"node-LatLon":{"lon":-1079081128,"lat":417014156}}},{"delta":{"node-LatLon":{"lon":-1079153926,"lat":416992506}}},{"delta":{"node-LatLon":{"lon":-1079226268,"lat":416970973}}},{"delta":{"node-LatLon":{"lon":-1079298175,"lat":416949594}}},{"delta":{"node-LatLon":{"lon":-1079370073,"lat":416928204}}},{"delta":{"node-LatLon":{"lon":-1079442362,"lat":416906685}}},{"delta":{"node-LatLon":{"lon":-1079513134,"lat":416882726}}},{"delta":{"node-LatLon":{"lon":-1079579019,"lat":416852706}}},{"delta":{"node-LatLon":{"lon":-1079644289,"lat":416822906}}},{"delta":{"node-LatLon":{"lon":-1079709585,"lat":416793141}}},{"delta":{"node-LatLon":{"lon":-1079776048,"lat":416762809}}},{"delta":{"node-LatLon":{"lon":-1079809278,"lat":416747641}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417284807,"long":-1077291383}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31288}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024653,"speed":24.46,"longitude":-105.0473207},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":71,"serialNumber":15500,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"00000000000002CC1B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415446372,"long":-1060853758},"name":"eastbound_I80_279.86_290.44_SAT-D603EB78_RC_LARI80WRAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060818850,"lat":415412221}}},{"delta":{"node-LatLon":{"lon":-1060795306,"lat":415389123}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}},{"delta":{"node-LatLon":{"lon":-1060748924,"lat":415342529}}},{"delta":{"node-LatLon":{"lon":-1060725901,"lat":415319138}}},{"delta":{"node-LatLon":{"lon":-1060702891,"lat":415295740}}},{"delta":{"node-LatLon":{"lon":-1060677392,"lat":415274709}}},{"delta":{"node-LatLon":{"lon":-1060645465,"lat":415259440}}},{"delta":{"node-LatLon":{"lon":-1060611694,"lat":415246452}}},{"delta":{"node-LatLon":{"lon":-1060583936,"lat":415227230}}},{"delta":{"node-LatLon":{"lon":-1060567112,"lat":415201829}}},{"delta":{"node-LatLon":{"lon":-1060559250,"lat":415173268}}},{"delta":{"node-LatLon":{"lon":-1060551848,"lat":415144627}}},{"delta":{"node-LatLon":{"lon":-1060544578,"lat":415115967}}},{"delta":{"node-LatLon":{"lon":-1060537212,"lat":415087321}}},{"delta":{"node-LatLon":{"lon":-1060528192,"lat":415058965}}},{"delta":{"node-LatLon":{"lon":-1060513843,"lat":415031898}}},{"delta":{"node-LatLon":{"lon":-1060498684,"lat":415005075}}},{"delta":{"node-LatLon":{"lon":-1060479584,"lat":414979768}}},{"delta":{"node-LatLon":{"lon":-1060454612,"lat":414957536}}},{"delta":{"node-LatLon":{"lon":-1060424994,"lat":414938765}}},{"delta":{"node-LatLon":{"lon":-1060394265,"lat":414920704}}},{"delta":{"node-LatLon":{"lon":-1060362947,"lat":414903230}}},{"delta":{"node-LatLon":{"lon":-1060331139,"lat":414886261}}},{"delta":{"node-LatLon":{"lon":-1060299282,"lat":414869343}}},{"delta":{"node-LatLon":{"lon":-1060267401,"lat":414852453}}},{"delta":{"node-LatLon":{"lon":-1060236377,"lat":414836034}}},{"delta":{"node-LatLon":{"lon":-1060205413,"lat":414819550}}},{"delta":{"node-LatLon":{"lon":-1060174405,"lat":414803116}}},{"delta":{"node-LatLon":{"lon":-1060143426,"lat":414786651}}},{"delta":{"node-LatLon":{"lon":-1060112442,"lat":414770191}}},{"delta":{"node-LatLon":{"lon":-1060080853,"lat":414753421}}},{"delta":{"node-LatLon":{"lon":-1060049273,"lat":414736640}}},{"delta":{"node-LatLon":{"lon":-1060017699,"lat":414719856}}},{"delta":{"node-LatLon":{"lon":-1059986118,"lat":414703079}}},{"delta":{"node-LatLon":{"lon":-1059954550,"lat":414686289}}},{"delta":{"node-LatLon":{"lon":-1059923262,"lat":414669701}}},{"delta":{"node-LatLon":{"lon":-1059892003,"lat":414653083}}},{"delta":{"node-LatLon":{"lon":-1059860748,"lat":414636462}}},{"delta":{"node-LatLon":{"lon":-1059830894,"lat":414618511}}},{"delta":{"node-LatLon":{"lon":-1059806580,"lat":414596316}}},{"delta":{"node-LatLon":{"lon":-1059783729,"lat":414573041}}},{"delta":{"node-LatLon":{"lon":-1059760839,"lat":414549787}}},{"delta":{"node-LatLon":{"lon":-1059737946,"lat":414526535}}},{"delta":{"node-LatLon":{"lon":-1059715065,"lat":414503278}}},{"delta":{"node-LatLon":{"lon":-1059692206,"lat":414480008}}},{"delta":{"node-LatLon":{"lon":-1059665100,"lat":414457204}}},{"delta":{"node-LatLon":{"lon":-1059630733,"lat":414440918}}},{"delta":{"node-LatLon":{"lon":-1059592047,"lat":414431361}}},{"delta":{"node-LatLon":{"lon":-1059552953,"lat":414422717}}},{"delta":{"node-LatLon":{"lon":-1059513468,"lat":414415217}}},{"delta":{"node-LatLon":{"lon":-1059476558,"lat":414409805}}},{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059421200,"lat":414401666}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415446372,"long":-1060853758}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024565,"speed":24.46,"longitude":-105.0473778},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":69,"serialNumber":15498,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000D0886","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416734737,"long":-1079825644},"name":"eastbound_I80_173.41_187.2_SAT-045A0F96_RC_WAMI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1079808962,"lat":416742355}}},{"delta":{"node-LatLon":{"lon":-1079775625,"lat":416757626}}},{"delta":{"node-LatLon":{"lon":-1079708864,"lat":416788062}}},{"delta":{"node-LatLon":{"lon":-1079643761,"lat":416817816}}},{"delta":{"node-LatLon":{"lon":-1079578633,"lat":416847544}}},{"delta":{"node-LatLon":{"lon":-1079513021,"lat":416877502}}},{"delta":{"node-LatLon":{"lon":-1079442840,"lat":416901685}}},{"delta":{"node-LatLon":{"lon":-1079370904,"lat":416923092}}},{"delta":{"node-LatLon":{"lon":-1079299318,"lat":416944401}}},{"delta":{"node-LatLon":{"lon":-1079227728,"lat":416965705}}},{"delta":{"node-LatLon":{"lon":-1079155246,"lat":416987264}}},{"delta":{"node-LatLon":{"lon":-1079081869,"lat":417009073}}},{"delta":{"node-LatLon":{"lon":-1079008281,"lat":417030466}}},{"delta":{"node-LatLon":{"lon":-1078933736,"lat":417045037}}},{"delta":{"node-LatLon":{"lon":-1078857144,"lat":417051301}}},{"delta":{"node-LatLon":{"lon":-1078779954,"lat":417053823}}},{"delta":{"node-LatLon":{"lon":-1078702612,"lat":417056324}}},{"delta":{"node-LatLon":{"lon":-1078625459,"lat":417053640}}},{"delta":{"node-LatLon":{"lon":-1078550508,"lat":417040669}}},{"delta":{"node-LatLon":{"lon":-1078475631,"lat":417027451}}},{"delta":{"node-LatLon":{"lon":-1078399078,"lat":417028105}}},{"delta":{"node-LatLon":{"lon":-1078325093,"lat":417044119}}},{"delta":{"node-LatLon":{"lon":-1078251401,"lat":417060961}}},{"delta":{"node-LatLon":{"lon":-1078177495,"lat":417077861}}},{"delta":{"node-LatLon":{"lon":-1078103576,"lat":417094732}}},{"delta":{"node-LatLon":{"lon":-1078029860,"lat":417111623}}},{"delta":{"node-LatLon":{"lon":-1077956308,"lat":417128437}}},{"delta":{"node-LatLon":{"lon":-1077882736,"lat":417145206}}},{"delta":{"node-LatLon":{"lon":-1077809037,"lat":417162072}}},{"delta":{"node-LatLon":{"lon":-1077735310,"lat":417178873}}},{"delta":{"node-LatLon":{"lon":-1077661395,"lat":417195740}}},{"delta":{"node-LatLon":{"lon":-1077587285,"lat":417212656}}},{"delta":{"node-LatLon":{"lon":-1077513154,"lat":417229528}}},{"delta":{"node-LatLon":{"lon":-1077440112,"lat":417246166}}},{"delta":{"node-LatLon":{"lon":-1077367083,"lat":417262839}}},{"delta":{"node-LatLon":{"lon":-1077292868,"lat":417279720}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416734737,"long":-1079825644}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024565,"speed":24.46,"longitude":-105.0473778},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":68,"serialNumber":15497,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"00000000000004E35A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415325796,"long":-1094614954},"name":"westbound_I80_90.098_90.312_SAT-5302F9D3_RC_GRTUNWB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094647572,"lat":415340958}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094677547,"lat":415358928}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000000100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415325796,"long":-1094614954}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024523,"speed":24.46,"longitude":-105.0474064},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":67,"serialNumber":15496,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000064D1D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415367224,"long":-1094697171},"name":"eastbound_I80_90.109_90.324_SAT-D48C7646_RC_GRTUNEB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094682069,"lat":415358380}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094651565,"lat":415340982}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000010000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415367224,"long":-1094697171}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024523,"speed":24.46,"longitude":-105.0474064},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":66,"serialNumber":15495,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000A389B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416780373,"long":-1087800160},"name":"westbound_I80_111.16_130.84_SAT-69F3DB7B_RC_RSI80ERAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087818098,"lat":416784087}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}},{"delta":{"node-LatLon":{"lon":-1087907758,"lat":416802744}}},{"delta":{"node-LatLon":{"lon":-1087979504,"lat":416817627}}},{"delta":{"node-LatLon":{"lon":-1088052834,"lat":416835667}}},{"delta":{"node-LatLon":{"lon":-1088118809,"lat":416865925}}},{"delta":{"node-LatLon":{"lon":-1088189118,"lat":416887479}}},{"delta":{"node-LatLon":{"lon":-1088265956,"lat":416884718}}},{"delta":{"node-LatLon":{"lon":-1088342780,"lat":416881687}}},{"delta":{"node-LatLon":{"lon":-1088419492,"lat":416886484}}},{"delta":{"node-LatLon":{"lon":-1088493522,"lat":416903350}}},{"delta":{"node-LatLon":{"lon":-1088567559,"lat":416920405}}},{"delta":{"node-LatLon":{"lon":-1088642038,"lat":416936455}}},{"delta":{"node-LatLon":{"lon":-1088718787,"lat":416933306}}},{"delta":{"node-LatLon":{"lon":-1088792811,"lat":416916445}}},{"delta":{"node-LatLon":{"lon":-1088868743,"lat":416911533}}},{"delta":{"node-LatLon":{"lon":-1088944838,"lat":416921259}}},{"delta":{"node-LatLon":{"lon":-1089020933,"lat":416916370}}},{"delta":{"node-LatLon":{"lon":-1089090262,"lat":416891382}}},{"delta":{"node-LatLon":{"lon":-1089158444,"lat":416862087}}},{"delta":{"node-LatLon":{"lon":-1089206739,"lat":416816167}}},{"delta":{"node-LatLon":{"lon":-1089229701,"lat":416761043}}},{"delta":{"node-LatLon":{"lon":-1089278517,"lat":416719880}}},{"delta":{"node-LatLon":{"lon":-1089348486,"lat":416699184}}},{"delta":{"node-LatLon":{"lon":-1089425832,"lat":416694198}}},{"delta":{"node-LatLon":{"lon":-1089503649,"lat":416693457}}},{"delta":{"node-LatLon":{"lon":-1089580254,"lat":416689749}}},{"delta":{"node-LatLon":{"lon":-1089654935,"lat":416679778}}},{"delta":{"node-LatLon":{"lon":-1089727701,"lat":416664462}}},{"delta":{"node-LatLon":{"lon":-1089800350,"lat":416634151}}},{"delta":{"node-LatLon":{"lon":-1089872661,"lat":416603374}}},{"delta":{"node-LatLon":{"lon":-1089942282,"lat":416573714}}},{"delta":{"node-LatLon":{"lon":-1090009243,"lat":416545210}}},{"delta":{"node-LatLon":{"lon":-1090076173,"lat":416516668}}},{"delta":{"node-LatLon":{"lon":-1090143069,"lat":416488162}}},{"delta":{"node-LatLon":{"lon":-1090209918,"lat":416459596}}},{"delta":{"node-LatLon":{"lon":-1090277470,"lat":416430810}}},{"delta":{"node-LatLon":{"lon":-1090345662,"lat":416401720}}},{"delta":{"node-LatLon":{"lon":-1090413831,"lat":416372606}}},{"delta":{"node-LatLon":{"lon":-1090485302,"lat":416354405}}},{"delta":{"node-LatLon":{"lon":-1090559312,"lat":416342147}}},{"delta":{"node-LatLon":{"lon":-1090633109,"lat":416329839}}},{"delta":{"node-LatLon":{"lon":-1090706742,"lat":416317644}}},{"delta":{"node-LatLon":{"lon":-1090780363,"lat":416305412}}},{"delta":{"node-LatLon":{"lon":-1090854362,"lat":416289159}}},{"delta":{"node-LatLon":{"lon":-1090923703,"lat":416263510}}},{"delta":{"node-LatLon":{"lon":-1090992931,"lat":416237673}}},{"delta":{"node-LatLon":{"lon":-1091062121,"lat":416211766}}},{"delta":{"node-LatLon":{"lon":-1091131370,"lat":416185951}}},{"delta":{"node-LatLon":{"lon":-1091198118,"lat":416160999}}},{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091281511,"lat":416129751}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000011111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416780373,"long":-1087800160}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024479,"speed":24.46,"longitude":-105.0474349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":65,"serialNumber":15494,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000002E727","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"eastbound_I80_111.16_130.84_SAT-E83FBA7D_RC_RSI80ERAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024479,"speed":24.46,"longitude":-105.0474349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":64,"serialNumber":15493,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"0000000000000EF239","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415272879,"long":-1094524441},"name":"westbound_I80_83.01_91.0_SAT-AE5C67DC_RC_RSI80WGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}},{"delta":{"node-LatLon":{"lon":-1094567629,"lat":415301333}}},{"delta":{"node-LatLon":{"lon":-1094598552,"lat":415318326}}},{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}},{"delta":{"node-LatLon":{"lon":-1094725523,"lat":415382855}}},{"delta":{"node-LatLon":{"lon":-1094759103,"lat":415397020}}},{"delta":{"node-LatLon":{"lon":-1094787376,"lat":415416158}}},{"delta":{"node-LatLon":{"lon":-1094803681,"lat":415442345}}},{"delta":{"node-LatLon":{"lon":-1094827523,"lat":415464696}}},{"delta":{"node-LatLon":{"lon":-1094857768,"lat":415483037}}},{"delta":{"node-LatLon":{"lon":-1094888001,"lat":415501390}}},{"delta":{"node-LatLon":{"lon":-1094919170,"lat":415518798}}},{"delta":{"node-LatLon":{"lon":-1094953846,"lat":415531903}}},{"delta":{"node-LatLon":{"lon":-1094991158,"lat":415539943}}},{"delta":{"node-LatLon":{"lon":-1095029104,"lat":415543908}}},{"delta":{"node-LatLon":{"lon":-1095067107,"lat":415547593}}},{"delta":{"node-LatLon":{"lon":-1095105120,"lat":415551220}}},{"delta":{"node-LatLon":{"lon":-1095142989,"lat":415555524}}},{"delta":{"node-LatLon":{"lon":-1095178583,"lat":415565942}}},{"delta":{"node-LatLon":{"lon":-1095212839,"lat":415581431}}},{"delta":{"node-LatLon":{"lon":-1095248825,"lat":415594355}}},{"delta":{"node-LatLon":{"lon":-1095287864,"lat":415600639}}},{"delta":{"node-LatLon":{"lon":-1095327361,"lat":415605311}}},{"delta":{"node-LatLon":{"lon":-1095366831,"lat":415610104}}},{"delta":{"node-LatLon":{"lon":-1095403172,"lat":415618111}}},{"delta":{"node-LatLon":{"lon":-1095437320,"lat":415630465}}},{"delta":{"node-LatLon":{"lon":-1095472268,"lat":415641378}}},{"delta":{"node-LatLon":{"lon":-1095509638,"lat":415645822}}},{"delta":{"node-LatLon":{"lon":-1095547341,"lat":415643461}}},{"delta":{"node-LatLon":{"lon":-1095583235,"lat":415634481}}},{"delta":{"node-LatLon":{"lon":-1095616942,"lat":415621427}}},{"delta":{"node-LatLon":{"lon":-1095650544,"lat":415608220}}},{"delta":{"node-LatLon":{"lon":-1095684389,"lat":415595379}}},{"delta":{"node-LatLon":{"lon":-1095720328,"lat":415586411}}},{"delta":{"node-LatLon":{"lon":-1095758260,"lat":415580697}}},{"delta":{"node-LatLon":{"lon":-1095796228,"lat":415575112}}},{"delta":{"node-LatLon":{"lon":-1095834193,"lat":415569520}}},{"delta":{"node-LatLon":{"lon":-1095872158,"lat":415563926}}},{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415272879,"long":-1094524441}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024436,"speed":24.46,"longitude":-105.0474634},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":63,"serialNumber":15492,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000004FE29","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415546021,"long":-1095927626},"name":"eastbound_I80_83.01_91.0_SAT-51917CF8_RC_RSI80WGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095910196,"lat":415552425}}},{"delta":{"node-LatLon":{"lon":-1095873554,"lat":415561468}}},{"delta":{"node-LatLon":{"lon":-1095835664,"lat":415567106}}},{"delta":{"node-LatLon":{"lon":-1095797758,"lat":415572690}}},{"delta":{"node-LatLon":{"lon":-1095759854,"lat":415578281}}},{"delta":{"node-LatLon":{"lon":-1095721965,"lat":415583926}}},{"delta":{"node-LatLon":{"lon":-1095685445,"lat":415592676}}},{"delta":{"node-LatLon":{"lon":-1095651117,"lat":415605559}}},{"delta":{"node-LatLon":{"lon":-1095617101,"lat":415618922}}},{"delta":{"node-LatLon":{"lon":-1095583008,"lat":415632176}}},{"delta":{"node-LatLon":{"lon":-1095546731,"lat":415641373}}},{"delta":{"node-LatLon":{"lon":-1095509731,"lat":415643672}}},{"delta":{"node-LatLon":{"lon":-1095473059,"lat":415639326}}},{"delta":{"node-LatLon":{"lon":-1095438752,"lat":415628644}}},{"delta":{"node-LatLon":{"lon":-1095405325,"lat":415616388}}},{"delta":{"node-LatLon":{"lon":-1095369730,"lat":415608358}}},{"delta":{"node-LatLon":{"lon":-1095330616,"lat":415603528}}},{"delta":{"node-LatLon":{"lon":-1095291457,"lat":415598888}}},{"delta":{"node-LatLon":{"lon":-1095252639,"lat":415593016}}},{"delta":{"node-LatLon":{"lon":-1095216703,"lat":415580638}}},{"delta":{"node-LatLon":{"lon":-1095182775,"lat":415565235}}},{"delta":{"node-LatLon":{"lon":-1095147149,"lat":415554096}}},{"delta":{"node-LatLon":{"lon":-1095108985,"lat":415549420}}},{"delta":{"node-LatLon":{"lon":-1095070589,"lat":415545729}}},{"delta":{"node-LatLon":{"lon":-1095032188,"lat":415542064}}},{"delta":{"node-LatLon":{"lon":-1094993831,"lat":415538174}}},{"delta":{"node-LatLon":{"lon":-1094956860,"lat":415530480}}},{"delta":{"node-LatLon":{"lon":-1094922411,"lat":415517802}}},{"delta":{"node-LatLon":{"lon":-1094891469,"lat":415500743}}},{"delta":{"node-LatLon":{"lon":-1094861594,"lat":415482600}}},{"delta":{"node-LatLon":{"lon":-1094831707,"lat":415464468}}},{"delta":{"node-LatLon":{"lon":-1094806972,"lat":415442662}}},{"delta":{"node-LatLon":{"lon":-1094790913,"lat":415416378}}},{"delta":{"node-LatLon":{"lon":-1094763585,"lat":415396461}}},{"delta":{"node-LatLon":{"lon":-1094730035,"lat":415382264}}},{"delta":{"node-LatLon":{"lon":-1094697171,"lat":415367224}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}},{"delta":{"node-LatLon":{"lon":-1094603326,"lat":415317623}}},{"delta":{"node-LatLon":{"lon":-1094571921,"lat":415301218}}},{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415546021,"long":-1095927626}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024392,"speed":24.46,"longitude":-105.047492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":62,"serialNumber":15491,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000059505","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-16CC040B_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024392,"speed":24.46,"longitude":-105.047492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":61,"serialNumber":15490,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000081102","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-6E2075B5_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.55,"latitude":41.1024304,"speed":24.32,"longitude":-105.047549},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":60,"serialNumber":15489,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000104155","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416142272,"long":-1091248169},"name":"westbound_I80_104.83_111.16_SAT-E4C7F6F3_RC_RSI80MARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091298228,"lat":416123561}}},{"delta":{"node-LatLon":{"lon":-1091334018,"lat":416110189}}},{"delta":{"node-LatLon":{"lon":-1091369795,"lat":416096798}}},{"delta":{"node-LatLon":{"lon":-1091405563,"lat":416083396}}},{"delta":{"node-LatLon":{"lon":-1091441283,"lat":416069923}}},{"delta":{"node-LatLon":{"lon":-1091474700,"lat":416053537}}},{"delta":{"node-LatLon":{"lon":-1091501964,"lat":416033828}}},{"delta":{"node-LatLon":{"lon":-1091526844,"lat":416012368}}},{"delta":{"node-LatLon":{"lon":-1091552241,"lat":415991270}}},{"delta":{"node-LatLon":{"lon":-1091583184,"lat":415974991}}},{"delta":{"node-LatLon":{"lon":-1091618832,"lat":415965599}}},{"delta":{"node-LatLon":{"lon":-1091657262,"lat":415963124}}},{"delta":{"node-LatLon":{"lon":-1091695868,"lat":415962098}}},{"delta":{"node-LatLon":{"lon":-1091734473,"lat":415961055}}},{"delta":{"node-LatLon":{"lon":-1091772519,"lat":415956756}}},{"delta":{"node-LatLon":{"lon":-1091806953,"lat":415943769}}},{"delta":{"node-LatLon":{"lon":-1091836882,"lat":415930461}}},{"delta":{"node-LatLon":{"lon":-1091869287,"lat":415921267}}},{"delta":{"node-LatLon":{"lon":-1091903898,"lat":415920097}}},{"delta":{"node-LatLon":{"lon":-1091937392,"lat":415926747}}},{"delta":{"node-LatLon":{"lon":-1091966574,"lat":415940771}}},{"delta":{"node-LatLon":{"lon":-1091990723,"lat":415963402}}},{"delta":{"node-LatLon":{"lon":-1092004823,"lat":415990502}}},{"delta":{"node-LatLon":{"lon":-1092019104,"lat":416017543}}},{"delta":{"node-LatLon":{"lon":-1092043521,"lat":416040022}}},{"delta":{"node-LatLon":{"lon":-1092074899,"lat":416057166}}},{"delta":{"node-LatLon":{"lon":-1092100017,"lat":416070268}}},{"delta":{"node-LatLon":{"lon":-1092125100,"lat":416083407}}},{"delta":{"node-LatLon":{"lon":-1092151035,"lat":416095519}}},{"delta":{"node-LatLon":{"lon":-1092180024,"lat":416102624}}},{"delta":{"node-LatLon":{"lon":-1092210485,"lat":416103734}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416142272,"long":-1091248169}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.55,"latitude":41.1024304,"speed":24.32,"longitude":-105.047549},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":59,"serialNumber":15488,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"0000000000000B625E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416070648,"long":-1092309469},"name":"eastbound_I80_104.83_111.16_SAT-7802A0B6_RC_RSI80MARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092256961,"lat":416090938}}},{"delta":{"node-LatLon":{"lon":-1092220011,"lat":416100743}}},{"delta":{"node-LatLon":{"lon":-1092180837,"lat":416100613}}},{"delta":{"node-LatLon":{"lon":-1092144100,"lat":416090411}}},{"delta":{"node-LatLon":{"lon":-1092111577,"lat":416073768}}},{"delta":{"node-LatLon":{"lon":-1092079251,"lat":416056897}}},{"delta":{"node-LatLon":{"lon":-1092047614,"lat":416039914}}},{"delta":{"node-LatLon":{"lon":-1092022496,"lat":416017802}}},{"delta":{"node-LatLon":{"lon":-1092007875,"lat":415990813}}},{"delta":{"node-LatLon":{"lon":-1091994030,"lat":415963562}}},{"delta":{"node-LatLon":{"lon":-1091970384,"lat":415940547}}},{"delta":{"node-LatLon":{"lon":-1091941029,"lat":415925731}}},{"delta":{"node-LatLon":{"lon":-1091907083,"lat":415918255}}},{"delta":{"node-LatLon":{"lon":-1091871710,"lat":415918755}}},{"delta":{"node-LatLon":{"lon":-1091838259,"lat":415927373}}},{"delta":{"node-LatLon":{"lon":-1091807633,"lat":415940869}}},{"delta":{"node-LatLon":{"lon":-1091773693,"lat":415954295}}},{"delta":{"node-LatLon":{"lon":-1091735915,"lat":415958860}}},{"delta":{"node-LatLon":{"lon":-1091697507,"lat":415959950}}},{"delta":{"node-LatLon":{"lon":-1091659097,"lat":415960991}}},{"delta":{"node-LatLon":{"lon":-1091620811,"lat":415963173}}},{"delta":{"node-LatLon":{"lon":-1091584800,"lat":415972056}}},{"delta":{"node-LatLon":{"lon":-1091553176,"lat":415987749}}},{"delta":{"node-LatLon":{"lon":-1091527289,"lat":416008625}}},{"delta":{"node-LatLon":{"lon":-1091502330,"lat":416030163}}},{"delta":{"node-LatLon":{"lon":-1091474365,"lat":416049452}}},{"delta":{"node-LatLon":{"lon":-1091440655,"lat":416065279}}},{"delta":{"node-LatLon":{"lon":-1091405002,"lat":416078597}}},{"delta":{"node-LatLon":{"lon":-1091369361,"lat":416091933}}},{"delta":{"node-LatLon":{"lon":-1091333716,"lat":416105264}}},{"delta":{"node-LatLon":{"lon":-1091298057,"lat":416118575}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416070648,"long":-1092309469}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024261,"speed":24.14,"longitude":-105.0475775},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":58,"serialNumber":15487,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31551,"packetID":"000000000000038ED9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416344087,"long":-1082586926},"name":"westbound_I80_142.17_158.55_SAT-BC3CEF3B_RC_PDI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082605867,"lat":416341147}}},{"delta":{"node-LatLon":{"lon":-1082643762,"lat":416335317}}},{"delta":{"node-LatLon":{"lon":-1082719537,"lat":416323607}}},{"delta":{"node-LatLon":{"lon":-1082795332,"lat":416311823}}},{"delta":{"node-LatLon":{"lon":-1082871219,"lat":416300396}}},{"delta":{"node-LatLon":{"lon":-1082948412,"lat":416300333}}},{"delta":{"node-LatLon":{"lon":-1083025592,"lat":416303069}}},{"delta":{"node-LatLon":{"lon":-1083102774,"lat":416305783}}},{"delta":{"node-LatLon":{"lon":-1083179715,"lat":416308441}}},{"delta":{"node-LatLon":{"lon":-1083256650,"lat":416311187}}},{"delta":{"node-LatLon":{"lon":-1083333670,"lat":416313866}}},{"delta":{"node-LatLon":{"lon":-1083410768,"lat":416316579}}},{"delta":{"node-LatLon":{"lon":-1083487872,"lat":416319193}}},{"delta":{"node-LatLon":{"lon":-1083564905,"lat":416322423}}},{"delta":{"node-LatLon":{"lon":-1083641683,"lat":416328142}}},{"delta":{"node-LatLon":{"lon":-1083718587,"lat":416332876}}},{"delta":{"node-LatLon":{"lon":-1083795496,"lat":416337572}}},{"delta":{"node-LatLon":{"lon":-1083872405,"lat":416342269}}},{"delta":{"node-LatLon":{"lon":-1083949300,"lat":416347096}}},{"delta":{"node-LatLon":{"lon":-1084026064,"lat":416352984}}},{"delta":{"node-LatLon":{"lon":-1084103063,"lat":416357400}}},{"delta":{"node-LatLon":{"lon":-1084180198,"lat":416361177}}},{"delta":{"node-LatLon":{"lon":-1084257244,"lat":416365879}}},{"delta":{"node-LatLon":{"lon":-1084326673,"lat":416370105}}},{"delta":{"node-LatLon":{"lon":-1084396100,"lat":416374353}}},{"delta":{"node-LatLon":{"lon":-1084469893,"lat":416378867}}},{"delta":{"node-LatLon":{"lon":-1084548056,"lat":416383611}}},{"delta":{"node-LatLon":{"lon":-1084626220,"lat":416388347}}},{"delta":{"node-LatLon":{"lon":-1084703702,"lat":416393060}}},{"delta":{"node-LatLon":{"lon":-1084781188,"lat":416397734}}},{"delta":{"node-LatLon":{"lon":-1084859010,"lat":416402450}}},{"delta":{"node-LatLon":{"lon":-1084937168,"lat":416407197}}},{"delta":{"node-LatLon":{"lon":-1085015328,"lat":416411930}}},{"delta":{"node-LatLon":{"lon":-1085093024,"lat":416416612}}},{"delta":{"node-LatLon":{"lon":-1085170718,"lat":416421321}}},{"delta":{"node-LatLon":{"lon":-1085248418,"lat":416425954}}},{"delta":{"node-LatLon":{"lon":-1085326100,"lat":416430747}}},{"delta":{"node-LatLon":{"lon":-1085403806,"lat":416435322}}},{"delta":{"node-LatLon":{"lon":-1085482142,"lat":416440051}}},{"delta":{"node-LatLon":{"lon":-1085560481,"lat":416444752}}},{"delta":{"node-LatLon":{"lon":-1085638702,"lat":416449395}}},{"delta":{"node-LatLon":{"lon":-1085716794,"lat":416454065}}},{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416344087,"long":-1082586926}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31551}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024175,"speed":24.14,"longitude":-105.0476338},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":55,"serialNumber":15484,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31448,"packetID":"000000000000078022","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416786287,"long":-1087839399},"name":"eastbound_I80_130.84_142.17_SAT-7FA0318B_RC_PDI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}},{"delta":{"node-LatLon":{"lon":-1087803620,"lat":416778902}}},{"delta":{"node-LatLon":{"lon":-1087765168,"lat":416771009}}},{"delta":{"node-LatLon":{"lon":-1087726370,"lat":416764174}}},{"delta":{"node-LatLon":{"lon":-1087686884,"lat":416760144}}},{"delta":{"node-LatLon":{"lon":-1087647203,"lat":416757279}}},{"delta":{"node-LatLon":{"lon":-1087607525,"lat":416754383}}},{"delta":{"node-LatLon":{"lon":-1087569186,"lat":416751628}}},{"delta":{"node-LatLon":{"lon":-1087530855,"lat":416748818}}},{"delta":{"node-LatLon":{"lon":-1087492521,"lat":416746033}}},{"delta":{"node-LatLon":{"lon":-1087454195,"lat":416743189}}},{"delta":{"node-LatLon":{"lon":-1087416702,"lat":416736770}}},{"delta":{"node-LatLon":{"lon":-1087381435,"lat":416725340}}},{"delta":{"node-LatLon":{"lon":-1087349578,"lat":416709238}}},{"delta":{"node-LatLon":{"lon":-1087320577,"lat":416690280}}},{"delta":{"node-LatLon":{"lon":-1087291648,"lat":416671260}}},{"delta":{"node-LatLon":{"lon":-1087262787,"lat":416652182}}},{"delta":{"node-LatLon":{"lon":-1087233802,"lat":416633016}}},{"delta":{"node-LatLon":{"lon":-1087204787,"lat":416613876}}},{"delta":{"node-LatLon":{"lon":-1087175815,"lat":416594699}}},{"delta":{"node-LatLon":{"lon":-1087146808,"lat":416575554}}},{"delta":{"node-LatLon":{"lon":-1087117854,"lat":416556364}}},{"delta":{"node-LatLon":{"lon":-1087088159,"lat":416538069}}},{"delta":{"node-LatLon":{"lon":-1087056409,"lat":416521833}}},{"delta":{"node-LatLon":{"lon":-1087022859,"lat":416507786}}},{"delta":{"node-LatLon":{"lon":-1086987709,"lat":416496142}}},{"delta":{"node-LatLon":{"lon":-1086951310,"lat":416486912}}},{"delta":{"node-LatLon":{"lon":-1086913467,"lat":416480171}}},{"delta":{"node-LatLon":{"lon":-1086874956,"lat":416476074}}},{"delta":{"node-LatLon":{"lon":-1086836114,"lat":416474482}}},{"delta":{"node-LatLon":{"lon":-1086797232,"lat":416473404}}},{"delta":{"node-LatLon":{"lon":-1086758350,"lat":416472330}}},{"delta":{"node-LatLon":{"lon":-1086719468,"lat":416471283}}},{"delta":{"node-LatLon":{"lon":-1086680585,"lat":416470225}}},{"delta":{"node-LatLon":{"lon":-1086641702,"lat":416469187}}},{"delta":{"node-LatLon":{"lon":-1086602819,"lat":416468148}}},{"delta":{"node-LatLon":{"lon":-1086563936,"lat":416467108}}},{"delta":{"node-LatLon":{"lon":-1086525511,"lat":416466317}}},{"delta":{"node-LatLon":{"lon":-1086487125,"lat":416467788}}},{"delta":{"node-LatLon":{"lon":-1086448944,"lat":416471177}}},{"delta":{"node-LatLon":{"lon":-1086410780,"lat":416474681}}},{"delta":{"node-LatLon":{"lon":-1086372613,"lat":416478166}}},{"delta":{"node-LatLon":{"lon":-1086334405,"lat":416481678}}},{"delta":{"node-LatLon":{"lon":-1086296197,"lat":416485199}}},{"delta":{"node-LatLon":{"lon":-1086257994,"lat":416488743}}},{"delta":{"node-LatLon":{"lon":-1086219779,"lat":416492224}}},{"delta":{"node-LatLon":{"lon":-1086181504,"lat":416495268}}},{"delta":{"node-LatLon":{"lon":-1086142990,"lat":416495887}}},{"delta":{"node-LatLon":{"lon":-1086104564,"lat":416493848}}},{"delta":{"node-LatLon":{"lon":-1086066501,"lat":416489365}}},{"delta":{"node-LatLon":{"lon":-1086028512,"lat":416484522}}},{"delta":{"node-LatLon":{"lon":-1085990518,"lat":416479699}}},{"delta":{"node-LatLon":{"lon":-1085952503,"lat":416474853}}},{"delta":{"node-LatLon":{"lon":-1085914496,"lat":416469967}}},{"delta":{"node-LatLon":{"lon":-1085876481,"lat":416465123}}},{"delta":{"node-LatLon":{"lon":-1085838471,"lat":416460258}}},{"delta":{"node-LatLon":{"lon":-1085800440,"lat":416455490}}},{"delta":{"node-LatLon":{"lon":-1085761374,"lat":416452277}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416786287,"long":-1087839399}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31448}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024218,"speed":24.14,"longitude":-105.0476056},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":57,"serialNumber":15486,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31551,"packetID":"00000000000004E0EC","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416455490,"long":-1085800440},"name":"eastbound_I80_142.17_158.55_SAT-A139FA35_RC_PDI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085780958,"lat":416453533}}},{"delta":{"node-LatLon":{"lon":-1085722182,"lat":416449943}}},{"delta":{"node-LatLon":{"lon":-1085643804,"lat":416445230}}},{"delta":{"node-LatLon":{"lon":-1085565424,"lat":416440540}}},{"delta":{"node-LatLon":{"lon":-1085487043,"lat":416435869}}},{"delta":{"node-LatLon":{"lon":-1085408668,"lat":416431146}}},{"delta":{"node-LatLon":{"lon":-1085330293,"lat":416426421}}},{"delta":{"node-LatLon":{"lon":-1085251916,"lat":416421727}}},{"delta":{"node-LatLon":{"lon":-1085173902,"lat":416416997}}},{"delta":{"node-LatLon":{"lon":-1085096242,"lat":416412330}}},{"delta":{"node-LatLon":{"lon":-1085018585,"lat":416407636}}},{"delta":{"node-LatLon":{"lon":-1084940663,"lat":416402897}}},{"delta":{"node-LatLon":{"lon":-1084862741,"lat":416398163}}},{"delta":{"node-LatLon":{"lon":-1084784815,"lat":416393472}}},{"delta":{"node-LatLon":{"lon":-1084706889,"lat":416388787}}},{"delta":{"node-LatLon":{"lon":-1084628972,"lat":416384031}}},{"delta":{"node-LatLon":{"lon":-1084551057,"lat":416379343}}},{"delta":{"node-LatLon":{"lon":-1084473154,"lat":416374560}}},{"delta":{"node-LatLon":{"lon":-1084399541,"lat":416370085}}},{"delta":{"node-LatLon":{"lon":-1084330227,"lat":416365845}}},{"delta":{"node-LatLon":{"lon":-1084260912,"lat":416361623}}},{"delta":{"node-LatLon":{"lon":-1084184275,"lat":416356906}}},{"delta":{"node-LatLon":{"lon":-1084107548,"lat":416353136}}},{"delta":{"node-LatLon":{"lon":-1084030065,"lat":416348811}}},{"delta":{"node-LatLon":{"lon":-1083951951,"lat":416342842}}},{"delta":{"node-LatLon":{"lon":-1083873709,"lat":416337915}}},{"delta":{"node-LatLon":{"lon":-1083796972,"lat":416333186}}},{"delta":{"node-LatLon":{"lon":-1083720234,"lat":416328459}}},{"delta":{"node-LatLon":{"lon":-1083643497,"lat":416323733}}},{"delta":{"node-LatLon":{"lon":-1083566759,"lat":416319020}}},{"delta":{"node-LatLon":{"lon":-1083489868,"lat":416316067}}},{"delta":{"node-LatLon":{"lon":-1083413019,"lat":416313460}}},{"delta":{"node-LatLon":{"lon":-1083336178,"lat":416310750}}},{"delta":{"node-LatLon":{"lon":-1083259199,"lat":416308063}}},{"delta":{"node-LatLon":{"lon":-1083182086,"lat":416305377}}},{"delta":{"node-LatLon":{"lon":-1083104978,"lat":416302622}}},{"delta":{"node-LatLon":{"lon":-1083028061,"lat":416299895}}},{"delta":{"node-LatLon":{"lon":-1082951147,"lat":416297144}}},{"delta":{"node-LatLon":{"lon":-1082873751,"lat":416296812}}},{"delta":{"node-LatLon":{"lon":-1082797210,"lat":416308158}}},{"delta":{"node-LatLon":{"lon":-1082720795,"lat":416320017}}},{"delta":{"node-LatLon":{"lon":-1082645377,"lat":416331711}}},{"delta":{"node-LatLon":{"lon":-1082607675,"lat":416337584}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416455490,"long":-1085800440}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31551}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024218,"speed":24.14,"longitude":-105.0476056},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":56,"serialNumber":15485,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31448,"packetID":"00000000000008DC26","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416456408,"long":-1085755840},"name":"westbound_I80_130.84_142.17_SAT-84100418_RC_PDI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}},{"delta":{"node-LatLon":{"lon":-1085794888,"lat":416458736}}},{"delta":{"node-LatLon":{"lon":-1085833690,"lat":416461832}}},{"delta":{"node-LatLon":{"lon":-1085872176,"lat":416466707}}},{"delta":{"node-LatLon":{"lon":-1085910651,"lat":416471634}}},{"delta":{"node-LatLon":{"lon":-1085949134,"lat":416476528}}},{"delta":{"node-LatLon":{"lon":-1085987613,"lat":416481440}}},{"delta":{"node-LatLon":{"lon":-1086025528,"lat":416486267}}},{"delta":{"node-LatLon":{"lon":-1086063443,"lat":416491103}}},{"delta":{"node-LatLon":{"lon":-1086101422,"lat":416495630}}},{"delta":{"node-LatLon":{"lon":-1086139754,"lat":416497851}}},{"delta":{"node-LatLon":{"lon":-1086178196,"lat":416497493}}},{"delta":{"node-LatLon":{"lon":-1086216694,"lat":416494658}}},{"delta":{"node-LatLon":{"lon":-1086255095,"lat":416491116}}},{"delta":{"node-LatLon":{"lon":-1086293500,"lat":416487604}}},{"delta":{"node-LatLon":{"lon":-1086331905,"lat":416484089}}},{"delta":{"node-LatLon":{"lon":-1086370307,"lat":416480557}}},{"delta":{"node-LatLon":{"lon":-1086408427,"lat":416477034}}},{"delta":{"node-LatLon":{"lon":-1086446550,"lat":416473535}}},{"delta":{"node-LatLon":{"lon":-1086484678,"lat":416470066}}},{"delta":{"node-LatLon":{"lon":-1086523010,"lat":416468441}}},{"delta":{"node-LatLon":{"lon":-1086561402,"lat":416469144}}},{"delta":{"node-LatLon":{"lon":-1086600122,"lat":416470197}}},{"delta":{"node-LatLon":{"lon":-1086638841,"lat":416471267}}},{"delta":{"node-LatLon":{"lon":-1086677561,"lat":416472320}}},{"delta":{"node-LatLon":{"lon":-1086716282,"lat":416473363}}},{"delta":{"node-LatLon":{"lon":-1086755004,"lat":416474397}}},{"delta":{"node-LatLon":{"lon":-1086793804,"lat":416475422}}},{"delta":{"node-LatLon":{"lon":-1086832605,"lat":416476448}}},{"delta":{"node-LatLon":{"lon":-1086871382,"lat":416477827}}},{"delta":{"node-LatLon":{"lon":-1086909854,"lat":416481660}}},{"delta":{"node-LatLon":{"lon":-1086947668,"lat":416488224}}},{"delta":{"node-LatLon":{"lon":-1086984094,"lat":416497241}}},{"delta":{"node-LatLon":{"lon":-1087019268,"lat":416508718}}},{"delta":{"node-LatLon":{"lon":-1087052913,"lat":416522538}}},{"delta":{"node-LatLon":{"lon":-1087084695,"lat":416538656}}},{"delta":{"node-LatLon":{"lon":-1087114440,"lat":416556828}}},{"delta":{"node-LatLon":{"lon":-1087143191,"lat":416575895}}},{"delta":{"node-LatLon":{"lon":-1087171993,"lat":416594919}}},{"delta":{"node-LatLon":{"lon":-1087200784,"lat":416613953}}},{"delta":{"node-LatLon":{"lon":-1087229590,"lat":416632975}}},{"delta":{"node-LatLon":{"lon":-1087258414,"lat":416651983}}},{"delta":{"node-LatLon":{"lon":-1087287411,"lat":416671131}}},{"delta":{"node-LatLon":{"lon":-1087316426,"lat":416690264}}},{"delta":{"node-LatLon":{"lon":-1087345506,"lat":416709342}}},{"delta":{"node-LatLon":{"lon":-1087377220,"lat":416725818}}},{"delta":{"node-LatLon":{"lon":-1087412334,"lat":416737800}}},{"delta":{"node-LatLon":{"lon":-1087450059,"lat":416744739}}},{"delta":{"node-LatLon":{"lon":-1087488730,"lat":416747863}}},{"delta":{"node-LatLon":{"lon":-1087527450,"lat":416750657}}},{"delta":{"node-LatLon":{"lon":-1087566170,"lat":416753452}}},{"delta":{"node-LatLon":{"lon":-1087604889,"lat":416756257}}},{"delta":{"node-LatLon":{"lon":-1087644394,"lat":416759090}}},{"delta":{"node-LatLon":{"lon":-1087683889,"lat":416761997}}},{"delta":{"node-LatLon":{"lon":-1087723223,"lat":416765852}}},{"delta":{"node-LatLon":{"lon":-1087761910,"lat":416772440}}},{"delta":{"node-LatLon":{"lon":-1087800160,"lat":416780373}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416456408,"long":-1085755840}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31448}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024175,"speed":24.14,"longitude":-105.0476338},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":54,"serialNumber":15483,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31205,"packetID":"000000000000053EE5","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415560658,"long":-1095891000},"name":"westbound_I80_66.17_83.01_SAT-B436F4C6_RC_GRAI80ERSD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}},{"delta":{"node-LatLon":{"lon":-1095944107,"lat":415543430}}},{"delta":{"node-LatLon":{"lon":-1096006459,"lat":415509058}}},{"delta":{"node-LatLon":{"lon":-1096069455,"lat":415475411}}},{"delta":{"node-LatLon":{"lon":-1096142938,"lat":415458428}}},{"delta":{"node-LatLon":{"lon":-1096220131,"lat":415454351}}},{"delta":{"node-LatLon":{"lon":-1096297661,"lat":415450429}}},{"delta":{"node-LatLon":{"lon":-1096375509,"lat":415446500}}},{"delta":{"node-LatLon":{"lon":-1096453356,"lat":415442570}}},{"delta":{"node-LatLon":{"lon":-1096529793,"lat":415438718}}},{"delta":{"node-LatLon":{"lon":-1096606229,"lat":415434853}}},{"delta":{"node-LatLon":{"lon":-1096682818,"lat":415430949}}},{"delta":{"node-LatLon":{"lon":-1096759566,"lat":415427053}}},{"delta":{"node-LatLon":{"lon":-1096836470,"lat":415426618}}},{"delta":{"node-LatLon":{"lon":-1096912173,"lat":415426953}}},{"delta":{"node-LatLon":{"lon":-1096987876,"lat":415427245}}},{"delta":{"node-LatLon":{"lon":-1097064311,"lat":415427583}}},{"delta":{"node-LatLon":{"lon":-1097141481,"lat":415427878}}},{"delta":{"node-LatLon":{"lon":-1097218650,"lat":415428173}}},{"delta":{"node-LatLon":{"lon":-1097295910,"lat":415428433}}},{"delta":{"node-LatLon":{"lon":-1097373170,"lat":415428724}}},{"delta":{"node-LatLon":{"lon":-1097450254,"lat":415429029}}},{"delta":{"node-LatLon":{"lon":-1097527162,"lat":415429272}}},{"delta":{"node-LatLon":{"lon":-1097604070,"lat":415429555}}},{"delta":{"node-LatLon":{"lon":-1097681194,"lat":415429816}}},{"delta":{"node-LatLon":{"lon":-1097758318,"lat":415430084}}},{"delta":{"node-LatLon":{"lon":-1097835692,"lat":415430343}}},{"delta":{"node-LatLon":{"lon":-1097913317,"lat":415430599}}},{"delta":{"node-LatLon":{"lon":-1097990942,"lat":415430851}}},{"delta":{"node-LatLon":{"lon":-1098065366,"lat":415431126}}},{"delta":{"node-LatLon":{"lon":-1098139791,"lat":415431337}}},{"delta":{"node-LatLon":{"lon":-1098216745,"lat":415431535}}},{"delta":{"node-LatLon":{"lon":-1098296228,"lat":415431795}}},{"delta":{"node-LatLon":{"lon":-1098375702,"lat":415431381}}},{"delta":{"node-LatLon":{"lon":-1098453162,"lat":415429222}}},{"delta":{"node-LatLon":{"lon":-1098530622,"lat":415427098}}},{"delta":{"node-LatLon":{"lon":-1098607730,"lat":415424827}}},{"delta":{"node-LatLon":{"lon":-1098684499,"lat":415422667}}},{"delta":{"node-LatLon":{"lon":-1098761268,"lat":415420511}}},{"delta":{"node-LatLon":{"lon":-1098838221,"lat":415418364}}},{"delta":{"node-LatLon":{"lon":-1098914903,"lat":415422678}}},{"delta":{"node-LatLon":{"lon":-1098990040,"lat":415435886}}},{"delta":{"node-LatLon":{"lon":-1099066262,"lat":415444919}}},{"delta":{"node-LatLon":{"lon":-1099124034,"lat":415441676}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415560658,"long":-1095891000}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31205}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024175,"speed":24.02,"longitude":-105.0476341},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":53,"serialNumber":15482,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000C0531","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415436014,"long":-1099144153},"name":"eastbound_I80_66.17_83.01_SAT-C94BB8D8_RC_GRAI80ERSI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1099125634,"lat":415439288}}},{"delta":{"node-LatLon":{"lon":-1099068840,"lat":415442454}}},{"delta":{"node-LatLon":{"lon":-1098994159,"lat":415432068}}},{"delta":{"node-LatLon":{"lon":-1098919298,"lat":415418672}}},{"delta":{"node-LatLon":{"lon":-1098841848,"lat":415413814}}},{"delta":{"node-LatLon":{"lon":-1098764064,"lat":415415860}}},{"delta":{"node-LatLon":{"lon":-1098686825,"lat":415418104}}},{"delta":{"node-LatLon":{"lon":-1098609587,"lat":415420386}}},{"delta":{"node-LatLon":{"lon":-1098532251,"lat":415422458}}},{"delta":{"node-LatLon":{"lon":-1098454828,"lat":415424612}}},{"delta":{"node-LatLon":{"lon":-1098377407,"lat":415426813}}},{"delta":{"node-LatLon":{"lon":-1098298392,"lat":415427231}}},{"delta":{"node-LatLon":{"lon":-1098219367,"lat":415427018}}},{"delta":{"node-LatLon":{"lon":-1098142482,"lat":415426813}}},{"delta":{"node-LatLon":{"lon":-1098067736,"lat":415426561}}},{"delta":{"node-LatLon":{"lon":-1097992991,"lat":415426314}}},{"delta":{"node-LatLon":{"lon":-1097915737,"lat":415426054}}},{"delta":{"node-LatLon":{"lon":-1097838483,"lat":415425798}}},{"delta":{"node-LatLon":{"lon":-1097761247,"lat":415425574}}},{"delta":{"node-LatLon":{"lon":-1097684029,"lat":415425298}}},{"delta":{"node-LatLon":{"lon":-1097606811,"lat":415425006}}},{"delta":{"node-LatLon":{"lon":-1097529582,"lat":415424747}}},{"delta":{"node-LatLon":{"lon":-1097452354,"lat":415424479}}},{"delta":{"node-LatLon":{"lon":-1097375180,"lat":415424173}}},{"delta":{"node-LatLon":{"lon":-1097298061,"lat":415423892}}},{"delta":{"node-LatLon":{"lon":-1097220943,"lat":415423592}}},{"delta":{"node-LatLon":{"lon":-1097143863,"lat":415423302}}},{"delta":{"node-LatLon":{"lon":-1097066784,"lat":415423022}}},{"delta":{"node-LatLon":{"lon":-1096989920,"lat":415422730}}},{"delta":{"node-LatLon":{"lon":-1096913273,"lat":415422418}}},{"delta":{"node-LatLon":{"lon":-1096836626,"lat":415422122}}},{"delta":{"node-LatLon":{"lon":-1096759032,"lat":415422540}}},{"delta":{"node-LatLon":{"lon":-1096681595,"lat":415426454}}},{"delta":{"node-LatLon":{"lon":-1096604890,"lat":415430398}}},{"delta":{"node-LatLon":{"lon":-1096528903,"lat":415434233}}},{"delta":{"node-LatLon":{"lon":-1096452915,"lat":415438069}}},{"delta":{"node-LatLon":{"lon":-1096375022,"lat":415442012}}},{"delta":{"node-LatLon":{"lon":-1096297130,"lat":415445968}}},{"delta":{"node-LatLon":{"lon":-1096219868,"lat":415449865}}},{"delta":{"node-LatLon":{"lon":-1096143253,"lat":415453868}}},{"delta":{"node-LatLon":{"lon":-1096070093,"lat":415470372}}},{"delta":{"node-LatLon":{"lon":-1096006307,"lat":415503454}}},{"delta":{"node-LatLon":{"lon":-1095944191,"lat":415538433}}},{"delta":{"node-LatLon":{"lon":-1095892161,"lat":415557599}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415436014,"long":-1099144153}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024175,"speed":24.02,"longitude":-105.0476341},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":52,"serialNumber":15481,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31214,"packetID":"0000000000000B2F91","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413575987,"long":-1103362302},"name":"westbound_I80_30.4_39.9_SAT-81C57B76_RC_LYMI80WEVAND","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1103379413,"lat":413570507}}},{"delta":{"node-LatLon":{"lon":-1103396581,"lat":413565130}}},{"delta":{"node-LatLon":{"lon":-1103431966,"lat":413556590}}},{"delta":{"node-LatLon":{"lon":-1103468559,"lat":413551740}}},{"delta":{"node-LatLon":{"lon":-1103505682,"lat":413550496}}},{"delta":{"node-LatLon":{"lon":-1103542862,"lat":413550244}}},{"delta":{"node-LatLon":{"lon":-1103582724,"lat":413550041}}},{"delta":{"node-LatLon":{"lon":-1103622586,"lat":413549804}}},{"delta":{"node-LatLon":{"lon":-1103662427,"lat":413549039}}},{"delta":{"node-LatLon":{"lon":-1103701626,"lat":413543839}}},{"delta":{"node-LatLon":{"lon":-1103738811,"lat":413533136}}},{"delta":{"node-LatLon":{"lon":-1103772015,"lat":413518736}}},{"delta":{"node-LatLon":{"lon":-1103804719,"lat":413503676}}},{"delta":{"node-LatLon":{"lon":-1103837423,"lat":413488615}}},{"delta":{"node-LatLon":{"lon":-1103870139,"lat":413473571}}},{"delta":{"node-LatLon":{"lon":-1103902852,"lat":413458525}}},{"delta":{"node-LatLon":{"lon":-1103935453,"lat":413443497}}},{"delta":{"node-LatLon":{"lon":-1103968058,"lat":413428474}}},{"delta":{"node-LatLon":{"lon":-1104000677,"lat":413413470}}},{"delta":{"node-LatLon":{"lon":-1104033300,"lat":413398472}}},{"delta":{"node-LatLon":{"lon":-1104066139,"lat":413383747}}},{"delta":{"node-LatLon":{"lon":-1104099921,"lat":413369977}}},{"delta":{"node-LatLon":{"lon":-1104134521,"lat":413357416}}},{"delta":{"node-LatLon":{"lon":-1104169857,"lat":413346086}}},{"delta":{"node-LatLon":{"lon":-1104205824,"lat":413335944}}},{"delta":{"node-LatLon":{"lon":-1104242388,"lat":413327102}}},{"delta":{"node-LatLon":{"lon":-1104279634,"lat":413319406}}},{"delta":{"node-LatLon":{"lon":-1104317320,"lat":413313051}}},{"delta":{"node-LatLon":{"lon":-1104355343,"lat":413307943}}},{"delta":{"node-LatLon":{"lon":-1104393408,"lat":413303019}}},{"delta":{"node-LatLon":{"lon":-1104431463,"lat":413298050}}},{"delta":{"node-LatLon":{"lon":-1104469251,"lat":413293160}}},{"delta":{"node-LatLon":{"lon":-1104507032,"lat":413288242}}},{"delta":{"node-LatLon":{"lon":-1104544821,"lat":413283359}}},{"delta":{"node-LatLon":{"lon":-1104582614,"lat":413278496}}},{"delta":{"node-LatLon":{"lon":-1104620358,"lat":413273425}}},{"delta":{"node-LatLon":{"lon":-1104657693,"lat":413266409}}},{"delta":{"node-LatLon":{"lon":-1104694040,"lat":413256888}}},{"delta":{"node-LatLon":{"lon":-1104729409,"lat":413245439}}},{"delta":{"node-LatLon":{"lon":-1104764689,"lat":413233834}}},{"delta":{"node-LatLon":{"lon":-1104799973,"lat":413222237}}},{"delta":{"node-LatLon":{"lon":-1104835095,"lat":413210680}}},{"delta":{"node-LatLon":{"lon":-1104870213,"lat":413199116}}},{"delta":{"node-LatLon":{"lon":-1104905341,"lat":413187570}}},{"delta":{"node-LatLon":{"lon":-1104940464,"lat":413176017}}},{"delta":{"node-LatLon":{"lon":-1104975588,"lat":413164466}}},{"delta":{"node-LatLon":{"lon":-1105010940,"lat":413152841}}},{"delta":{"node-LatLon":{"lon":-1105046305,"lat":413141239}}},{"delta":{"node-LatLon":{"lon":-1105081636,"lat":413129581}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000110000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413575987,"long":-1103362302}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31214}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024133,"speed":24.02,"longitude":-105.0476621},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":51,"serialNumber":15480,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000008948B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413121024,"long":-1105099337},"name":"eastbound_I80_30.4_39.9_SAT-2B017F7E_RC_LYMI80WEVANI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1105081780,"lat":413126737}}},{"delta":{"node-LatLon":{"lon":-1105046721,"lat":413138259}}},{"delta":{"node-LatLon":{"lon":-1105011682,"lat":413149818}}},{"delta":{"node-LatLon":{"lon":-1104976636,"lat":413161366}}},{"delta":{"node-LatLon":{"lon":-1104941339,"lat":413172988}}},{"delta":{"node-LatLon":{"lon":-1104906045,"lat":413184616}}},{"delta":{"node-LatLon":{"lon":-1104870749,"lat":413196242}}},{"delta":{"node-LatLon":{"lon":-1104835431,"lat":413207831}}},{"delta":{"node-LatLon":{"lon":-1104800118,"lat":413219429}}},{"delta":{"node-LatLon":{"lon":-1104764982,"lat":413230978}}},{"delta":{"node-LatLon":{"lon":-1104729863,"lat":413242558}}},{"delta":{"node-LatLon":{"lon":-1104694662,"lat":413253995}}},{"delta":{"node-LatLon":{"lon":-1104658541,"lat":413263634}}},{"delta":{"node-LatLon":{"lon":-1104621387,"lat":413270688}}},{"delta":{"node-LatLon":{"lon":-1104583599,"lat":413275784}}},{"delta":{"node-LatLon":{"lon":-1104545768,"lat":413280701}}},{"delta":{"node-LatLon":{"lon":-1104507932,"lat":413285595}}},{"delta":{"node-LatLon":{"lon":-1104470107,"lat":413290537}}},{"delta":{"node-LatLon":{"lon":-1104432261,"lat":413295393}}},{"delta":{"node-LatLon":{"lon":-1104394348,"lat":413300372}}},{"delta":{"node-LatLon":{"lon":-1104356408,"lat":413305233}}},{"delta":{"node-LatLon":{"lon":-1104318509,"lat":413310273}}},{"delta":{"node-LatLon":{"lon":-1104280839,"lat":413316200}}},{"delta":{"node-LatLon":{"lon":-1104243586,"lat":413323475}}},{"delta":{"node-LatLon":{"lon":-1104206850,"lat":413331998}}},{"delta":{"node-LatLon":{"lon":-1104170685,"lat":413341807}}},{"delta":{"node-LatLon":{"lon":-1104135154,"lat":413352860}}},{"delta":{"node-LatLon":{"lon":-1104100355,"lat":413365166}}},{"delta":{"node-LatLon":{"lon":-1104066322,"lat":413378639}}},{"delta":{"node-LatLon":{"lon":-1104032685,"lat":413393491}}},{"delta":{"node-LatLon":{"lon":-1103999387,"lat":413408776}}},{"delta":{"node-LatLon":{"lon":-1103966118,"lat":413424098}}},{"delta":{"node-LatLon":{"lon":-1103932864,"lat":413439440}}},{"delta":{"node-LatLon":{"lon":-1103899565,"lat":413454727}}},{"delta":{"node-LatLon":{"lon":-1103867253,"lat":413469609}}},{"delta":{"node-LatLon":{"lon":-1103835035,"lat":413484430}}},{"delta":{"node-LatLon":{"lon":-1103802824,"lat":413499260}}},{"delta":{"node-LatLon":{"lon":-1103770586,"lat":413514056}}},{"delta":{"node-LatLon":{"lon":-1103738028,"lat":413528436}}},{"delta":{"node-LatLon":{"lon":-1103701332,"lat":413539215}}},{"delta":{"node-LatLon":{"lon":-1103662594,"lat":413544545}}},{"delta":{"node-LatLon":{"lon":-1103623171,"lat":413545277}}},{"delta":{"node-LatLon":{"lon":-1103583727,"lat":413545520}}},{"delta":{"node-LatLon":{"lon":-1103544283,"lat":413545768}}},{"delta":{"node-LatLon":{"lon":-1103506786,"lat":413545969}}},{"delta":{"node-LatLon":{"lon":-1103469334,"lat":413547162}}},{"delta":{"node-LatLon":{"lon":-1103432403,"lat":413551942}}},{"delta":{"node-LatLon":{"lon":-1103396637,"lat":413560362}}},{"delta":{"node-LatLon":{"lon":-1103379293,"lat":413565730}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413121024,"long":-1105099337}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":47,"serialNumber":15476,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.453Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000B2362","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414323150,"long":-1101107194},"name":"eastbound_I80_53.31_66.17_SAT-19D61E53_RC_GRAI80WLYMI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1101089557,"lat":414329241}}},{"delta":{"node-LatLon":{"lon":-1101036650,"lat":414347521}}},{"delta":{"node-LatLon":{"lon":-1100968154,"lat":414374868}}},{"delta":{"node-LatLon":{"lon":-1100906030,"lat":414408931}}},{"delta":{"node-LatLon":{"lon":-1100844476,"lat":414443598}}},{"delta":{"node-LatLon":{"lon":-1100783084,"lat":414478183}}},{"delta":{"node-LatLon":{"lon":-1100721845,"lat":414512678}}},{"delta":{"node-LatLon":{"lon":-1100660589,"lat":414547159}}},{"delta":{"node-LatLon":{"lon":-1100598696,"lat":414582011}}},{"delta":{"node-LatLon":{"lon":-1100536824,"lat":414616882}}},{"delta":{"node-LatLon":{"lon":-1100472780,"lat":414652911}}},{"delta":{"node-LatLon":{"lon":-1100407893,"lat":414691351}}},{"delta":{"node-LatLon":{"lon":-1100352218,"lat":414737180}}},{"delta":{"node-LatLon":{"lon":-1100303788,"lat":414782434}}},{"delta":{"node-LatLon":{"lon":-1100255356,"lat":414827689}}},{"delta":{"node-LatLon":{"lon":-1100207264,"lat":414872624}}},{"delta":{"node-LatLon":{"lon":-1100156738,"lat":414915457}}},{"delta":{"node-LatLon":{"lon":-1100105308,"lat":414957699}}},{"delta":{"node-LatLon":{"lon":-1100048563,"lat":414996592}}},{"delta":{"node-LatLon":{"lon":-1099984833,"lat":415028931}}},{"delta":{"node-LatLon":{"lon":-1099920979,"lat":415061041}}},{"delta":{"node-LatLon":{"lon":-1099857029,"lat":415092941}}},{"delta":{"node-LatLon":{"lon":-1099792739,"lat":415124448}}},{"delta":{"node-LatLon":{"lon":-1099728759,"lat":415156288}}},{"delta":{"node-LatLon":{"lon":-1099664735,"lat":415188081}}},{"delta":{"node-LatLon":{"lon":-1099600327,"lat":415220093}}},{"delta":{"node-LatLon":{"lon":-1099535522,"lat":415252310}}},{"delta":{"node-LatLon":{"lon":-1099470701,"lat":415284512}}},{"delta":{"node-LatLon":{"lon":-1099406151,"lat":415316553}}},{"delta":{"node-LatLon":{"lon":-1099341572,"lat":415348565}}},{"delta":{"node-LatLon":{"lon":-1099277375,"lat":415380463}}},{"delta":{"node-LatLon":{"lon":-1099213464,"lat":415412136}}},{"delta":{"node-LatLon":{"lon":-1099144153,"lat":415436014}}},{"delta":{"node-LatLon":{"lon":-1099106846,"lat":415441537}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111000000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414323150,"long":-1101107194}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024133,"speed":24.02,"longitude":-105.0476621},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":50,"serialNumber":15479,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31214,"packetID":"0000000000000A659A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414344751,"long":-1101051424},"name":"westbound_I80_39.9_53.31_SAT-08844513_RC_LYMI80EGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1101068786,"lat":414338729}}},{"delta":{"node-LatLon":{"lon":-1101103554,"lat":414326761}}},{"delta":{"node-LatLon":{"lon":-1101173821,"lat":414302516}}},{"delta":{"node-LatLon":{"lon":-1101244744,"lat":414277845}}},{"delta":{"node-LatLon":{"lon":-1101310950,"lat":414246773}}},{"delta":{"node-LatLon":{"lon":-1101362064,"lat":414212123}}},{"delta":{"node-LatLon":{"lon":-1101407558,"lat":414173212}}},{"delta":{"node-LatLon":{"lon":-1101456142,"lat":414132500}}},{"delta":{"node-LatLon":{"lon":-1101515051,"lat":414095801}}},{"delta":{"node-LatLon":{"lon":-1101578308,"lat":414063326}}},{"delta":{"node-LatLon":{"lon":-1101641229,"lat":414030925}}},{"delta":{"node-LatLon":{"lon":-1101704290,"lat":413998477}}},{"delta":{"node-LatLon":{"lon":-1101767097,"lat":413966110}}},{"delta":{"node-LatLon":{"lon":-1101831402,"lat":413935792}}},{"delta":{"node-LatLon":{"lon":-1101901550,"lat":413914120}}},{"delta":{"node-LatLon":{"lon":-1101976786,"lat":413898894}}},{"delta":{"node-LatLon":{"lon":-1102052080,"lat":413883827}}},{"delta":{"node-LatLon":{"lon":-1102126907,"lat":413868839}}},{"delta":{"node-LatLon":{"lon":-1102200439,"lat":413851903}}},{"delta":{"node-LatLon":{"lon":-1102269103,"lat":413825929}}},{"delta":{"node-LatLon":{"lon":-1102332567,"lat":413793094}}},{"delta":{"node-LatLon":{"lon":-1102398732,"lat":413763591}}},{"delta":{"node-LatLon":{"lon":-1102470298,"lat":413743958}}},{"delta":{"node-LatLon":{"lon":-1102543982,"lat":413731406}}},{"delta":{"node-LatLon":{"lon":-1102617848,"lat":413719488}}},{"delta":{"node-LatLon":{"lon":-1102692470,"lat":413710650}}},{"delta":{"node-LatLon":{"lon":-1102767178,"lat":413702215}}},{"delta":{"node-LatLon":{"lon":-1102843114,"lat":413693602}}},{"delta":{"node-LatLon":{"lon":-1102920289,"lat":413684874}}},{"delta":{"node-LatLon":{"lon":-1102996200,"lat":413671478}}},{"delta":{"node-LatLon":{"lon":-1103069136,"lat":413655627}}},{"delta":{"node-LatLon":{"lon":-1103142026,"lat":413639808}}},{"delta":{"node-LatLon":{"lon":-1103216030,"lat":413622306}}},{"delta":{"node-LatLon":{"lon":-1103289209,"lat":413599223}}},{"delta":{"node-LatLon":{"lon":-1103362302,"lat":413575987}}},{"delta":{"node-LatLon":{"lon":-1103379413,"lat":413570507}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001110000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414344751,"long":-1101051424}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31214}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.102409,"speed":24.02,"longitude":-105.0476902},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":49,"serialNumber":15478,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000019B21","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413560362,"long":-1103396637},"name":"eastbound_I80_39.9_53.31_SAT-A835ACAE_RC_LYMI80EGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1103379293,"lat":413565730}}},{"delta":{"node-LatLon":{"lon":-1103362018,"lat":413571225}}},{"delta":{"node-LatLon":{"lon":-1103289477,"lat":413594336}}},{"delta":{"node-LatLon":{"lon":-1103216886,"lat":413617361}}},{"delta":{"node-LatLon":{"lon":-1103144075,"lat":413634764}}},{"delta":{"node-LatLon":{"lon":-1103072890,"lat":413650240}}},{"delta":{"node-LatLon":{"lon":-1103001562,"lat":413665711}}},{"delta":{"node-LatLon":{"lon":-1102924478,"lat":413679917}}},{"delta":{"node-LatLon":{"lon":-1102845931,"lat":413688783}}},{"delta":{"node-LatLon":{"lon":-1102769203,"lat":413697491}}},{"delta":{"node-LatLon":{"lon":-1102694282,"lat":413705973}}},{"delta":{"node-LatLon":{"lon":-1102619427,"lat":413714771}}},{"delta":{"node-LatLon":{"lon":-1102543987,"lat":413726889}}},{"delta":{"node-LatLon":{"lon":-1102468757,"lat":413739737}}},{"delta":{"node-LatLon":{"lon":-1102396564,"lat":413759508}}},{"delta":{"node-LatLon":{"lon":-1102330529,"lat":413788757}}},{"delta":{"node-LatLon":{"lon":-1102267374,"lat":413821547}}},{"delta":{"node-LatLon":{"lon":-1102198471,"lat":413847770}}},{"delta":{"node-LatLon":{"lon":-1102124566,"lat":413864728}}},{"delta":{"node-LatLon":{"lon":-1102050308,"lat":413879597}}},{"delta":{"node-LatLon":{"lon":-1101976512,"lat":413894383}}},{"delta":{"node-LatLon":{"lon":-1101902756,"lat":413909284}}},{"delta":{"node-LatLon":{"lon":-1101831568,"lat":413930764}}},{"delta":{"node-LatLon":{"lon":-1101766297,"lat":413961147}}},{"delta":{"node-LatLon":{"lon":-1101702710,"lat":413993844}}},{"delta":{"node-LatLon":{"lon":-1101638962,"lat":414026618}}},{"delta":{"node-LatLon":{"lon":-1101574959,"lat":414059103}}},{"delta":{"node-LatLon":{"lon":-1101503795,"lat":414079486}}},{"delta":{"node-LatLon":{"lon":-1101430050,"lat":414094635}}},{"delta":{"node-LatLon":{"lon":-1101364010,"lat":414123142}}},{"delta":{"node-LatLon":{"lon":-1101315879,"lat":414167652}}},{"delta":{"node-LatLon":{"lon":-1101285137,"lat":414220512}}},{"delta":{"node-LatLon":{"lon":-1101240865,"lat":414267227}}},{"delta":{"node-LatLon":{"lon":-1101177309,"lat":414298942}}},{"delta":{"node-LatLon":{"lon":-1101107194,"lat":414323150}}},{"delta":{"node-LatLon":{"lon":-1101071949,"lat":414335378}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111000000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413560362,"long":-1103396637}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1024004,"speed":23.76,"longitude":-105.0477462},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":48,"serialNumber":15477,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.453Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31329,"packetID":"0000000000000D30E2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415444795,"long":-1099085600},"name":"westbound_I80_53.31_66.17_SAT-4E185B11_RC_GRAI80WLYMD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1099104884,"lat":415443688}}},{"delta":{"node-LatLon":{"lon":-1099142907,"lat":415438499}}},{"delta":{"node-LatLon":{"lon":-1099213633,"lat":415416960}}},{"delta":{"node-LatLon":{"lon":-1099277798,"lat":415385610}}},{"delta":{"node-LatLon":{"lon":-1099341920,"lat":415353771}}},{"delta":{"node-LatLon":{"lon":-1099406318,"lat":415321821}}},{"delta":{"node-LatLon":{"lon":-1099470693,"lat":415289849}}},{"delta":{"node-LatLon":{"lon":-1099535924,"lat":415257482}}},{"delta":{"node-LatLon":{"lon":-1099601115,"lat":415225072}}},{"delta":{"node-LatLon":{"lon":-1099665873,"lat":415192909}}},{"delta":{"node-LatLon":{"lon":-1099730154,"lat":415160943}}},{"delta":{"node-LatLon":{"lon":-1099794423,"lat":415128966}}},{"delta":{"node-LatLon":{"lon":-1099858611,"lat":415097082}}},{"delta":{"node-LatLon":{"lon":-1099922767,"lat":415065163}}},{"delta":{"node-LatLon":{"lon":-1099986894,"lat":415033282}}},{"delta":{"node-LatLon":{"lon":-1100050552,"lat":415000958}}},{"delta":{"node-LatLon":{"lon":-1100107537,"lat":414962342}}},{"delta":{"node-LatLon":{"lon":-1100159317,"lat":414919942}}},{"delta":{"node-LatLon":{"lon":-1100210275,"lat":414877000}}},{"delta":{"node-LatLon":{"lon":-1100258455,"lat":414831964}}},{"delta":{"node-LatLon":{"lon":-1100306816,"lat":414786740}}},{"delta":{"node-LatLon":{"lon":-1100355125,"lat":414741487}}},{"delta":{"node-LatLon":{"lon":-1100406269,"lat":414698457}}},{"delta":{"node-LatLon":{"lon":-1100466077,"lat":414662270}}},{"delta":{"node-LatLon":{"lon":-1100529550,"lat":414626554}}},{"delta":{"node-LatLon":{"lon":-1100594995,"lat":414589736}}},{"delta":{"node-LatLon":{"lon":-1100660445,"lat":414552926}}},{"delta":{"node-LatLon":{"lon":-1100720966,"lat":414518811}}},{"delta":{"node-LatLon":{"lon":-1100781507,"lat":414484719}}},{"delta":{"node-LatLon":{"lon":-1100843008,"lat":414450048}}},{"delta":{"node-LatLon":{"lon":-1100905513,"lat":414414842}}},{"delta":{"node-LatLon":{"lon":-1100968090,"lat":414379712}}},{"delta":{"node-LatLon":{"lon":-1101034065,"lat":414350776}}},{"delta":{"node-LatLon":{"lon":-1101086165,"lat":414332737}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001110000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415444795,"long":-1099085600}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31329}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":46,"serialNumber":15475,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000AA646","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413135480,"long":-1105064011},"name":"westbound_I80_18.29_30.4_SAT-4E8C2D1C_RC_EVANI80ELYM2D","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1105081636,"lat":413129581}}},{"delta":{"node-LatLon":{"lon":-1105152429,"lat":413106493}}},{"delta":{"node-LatLon":{"lon":-1105222681,"lat":413083154}}},{"delta":{"node-LatLon":{"lon":-1105293041,"lat":413060007}}},{"delta":{"node-LatLon":{"lon":-1105365675,"lat":413036053}}},{"delta":{"node-LatLon":{"lon":-1105440576,"lat":413011281}}},{"delta":{"node-LatLon":{"lon":-1105515498,"lat":412986550}}},{"delta":{"node-LatLon":{"lon":-1105587007,"lat":412974643}}},{"delta":{"node-LatLon":{"lon":-1105660608,"lat":412975574}}},{"delta":{"node-LatLon":{"lon":-1105734210,"lat":412976799}}},{"delta":{"node-LatLon":{"lon":-1105807811,"lat":412978023}}},{"delta":{"node-LatLon":{"lon":-1105881411,"lat":412979276}}},{"delta":{"node-LatLon":{"lon":-1105958106,"lat":412980598}}},{"delta":{"node-LatLon":{"lon":-1106034803,"lat":412981835}}},{"delta":{"node-LatLon":{"lon":-1106111006,"lat":412983091}}},{"delta":{"node-LatLon":{"lon":-1106186716,"lat":412984304}}},{"delta":{"node-LatLon":{"lon":-1106262425,"lat":412985553}}},{"delta":{"node-LatLon":{"lon":-1106340719,"lat":412986812}}},{"delta":{"node-LatLon":{"lon":-1106419013,"lat":412988052}}},{"delta":{"node-LatLon":{"lon":-1106496051,"lat":412989281}}},{"delta":{"node-LatLon":{"lon":-1106571818,"lat":412990824}}},{"delta":{"node-LatLon":{"lon":-1106647599,"lat":412992029}}},{"delta":{"node-LatLon":{"lon":-1106726085,"lat":412993268}}},{"delta":{"node-LatLon":{"lon":-1106803345,"lat":412986953}}},{"delta":{"node-LatLon":{"lon":-1106867780,"lat":412955347}}},{"delta":{"node-LatLon":{"lon":-1106940824,"lat":412955290}}},{"delta":{"node-LatLon":{"lon":-1107004030,"lat":412986369}}},{"delta":{"node-LatLon":{"lon":-1107075211,"lat":413008691}}},{"delta":{"node-LatLon":{"lon":-1107146451,"lat":413030911}}},{"delta":{"node-LatLon":{"lon":-1107217304,"lat":413052985}}},{"delta":{"node-LatLon":{"lon":-1107287759,"lat":413074934}}},{"delta":{"node-LatLon":{"lon":-1107323024,"lat":413085837}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413135480,"long":-1105064011}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":45,"serialNumber":15474,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000103B16","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413088220,"long":-1107346769},"name":"eastbound_I80_18.29_30.4_SAT-1BB0E1D9_RC_EVANI80ELYM2I","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1107327853,"lat":413085207}}},{"delta":{"node-LatLon":{"lon":-1107291892,"lat":413074355}}},{"delta":{"node-LatLon":{"lon":-1107220291,"lat":413052030}}},{"delta":{"node-LatLon":{"lon":-1107148980,"lat":413029795}}},{"delta":{"node-LatLon":{"lon":-1107078119,"lat":413007369}}},{"delta":{"node-LatLon":{"lon":-1107007132,"lat":412985172}}},{"delta":{"node-LatLon":{"lon":-1106941741,"lat":412953720}}},{"delta":{"node-LatLon":{"lon":-1106866866,"lat":412953036}}},{"delta":{"node-LatLon":{"lon":-1106802203,"lat":412985015}}},{"delta":{"node-LatLon":{"lon":-1106726168,"lat":412991195}}},{"delta":{"node-LatLon":{"lon":-1106648917,"lat":412989976}}},{"delta":{"node-LatLon":{"lon":-1106573197,"lat":412988796}}},{"delta":{"node-LatLon":{"lon":-1106497477,"lat":412987600}}},{"delta":{"node-LatLon":{"lon":-1106420644,"lat":412986371}}},{"delta":{"node-LatLon":{"lon":-1106342697,"lat":412985100}}},{"delta":{"node-LatLon":{"lon":-1106264749,"lat":412983842}}},{"delta":{"node-LatLon":{"lon":-1106189077,"lat":412982627}}},{"delta":{"node-LatLon":{"lon":-1106113405,"lat":412981388}}},{"delta":{"node-LatLon":{"lon":-1106037230,"lat":412980142}}},{"delta":{"node-LatLon":{"lon":-1105960566,"lat":412978554}}},{"delta":{"node-LatLon":{"lon":-1105883887,"lat":412977263}}},{"delta":{"node-LatLon":{"lon":-1105807259,"lat":412976192}}},{"delta":{"node-LatLon":{"lon":-1105730649,"lat":412974694}}},{"delta":{"node-LatLon":{"lon":-1105656816,"lat":412973443}}},{"delta":{"node-LatLon":{"lon":-1105585775,"lat":412972496}}},{"delta":{"node-LatLon":{"lon":-1105516502,"lat":412983227}}},{"delta":{"node-LatLon":{"lon":-1105441920,"lat":413008048}}},{"delta":{"node-LatLon":{"lon":-1105367237,"lat":413032710}}},{"delta":{"node-LatLon":{"lon":-1105294291,"lat":413056763}}},{"delta":{"node-LatLon":{"lon":-1105223123,"lat":413080276}}},{"delta":{"node-LatLon":{"lon":-1105151956,"lat":413103795}}},{"delta":{"node-LatLon":{"lon":-1105081780,"lat":413126737}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413088220,"long":-1107346769}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":44,"serialNumber":15473,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000E3CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413074934,"long":-1107287759},"name":"westbound_I80_6.26_18.29_SAT-6167B0AE_RC_EVANI80ELYMD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1107305366,"lat":413080434}}},{"delta":{"node-LatLon":{"lon":-1107360431,"lat":413090250}}},{"delta":{"node-LatLon":{"lon":-1107435889,"lat":413072542}}},{"delta":{"node-LatLon":{"lon":-1107510137,"lat":413051412}}},{"delta":{"node-LatLon":{"lon":-1107583237,"lat":413030611}}},{"delta":{"node-LatLon":{"lon":-1107651303,"lat":413004057}}},{"delta":{"node-LatLon":{"lon":-1107715511,"lat":412972132}}},{"delta":{"node-LatLon":{"lon":-1107779433,"lat":412939683}}},{"delta":{"node-LatLon":{"lon":-1107834761,"lat":412899298}}},{"delta":{"node-LatLon":{"lon":-1107888585,"lat":412858118}}},{"delta":{"node-LatLon":{"lon":-1107942218,"lat":412817220}}},{"delta":{"node-LatLon":{"lon":-1107995791,"lat":412776279}}},{"delta":{"node-LatLon":{"lon":-1108052203,"lat":412738880}}},{"delta":{"node-LatLon":{"lon":-1108125567,"lat":412730945}}},{"delta":{"node-LatLon":{"lon":-1108200890,"lat":412730979}}},{"delta":{"node-LatLon":{"lon":-1108269016,"lat":412705671}}},{"delta":{"node-LatLon":{"lon":-1108336945,"lat":412680037}}},{"delta":{"node-LatLon":{"lon":-1108412418,"lat":412681664}}},{"delta":{"node-LatLon":{"lon":-1108481367,"lat":412706514}}},{"delta":{"node-LatLon":{"lon":-1108552780,"lat":412726456}}},{"delta":{"node-LatLon":{"lon":-1108625458,"lat":412710792}}},{"delta":{"node-LatLon":{"lon":-1108688492,"lat":412677244}}},{"delta":{"node-LatLon":{"lon":-1108755794,"lat":412649329}}},{"delta":{"node-LatLon":{"lon":-1108828743,"lat":412631226}}},{"delta":{"node-LatLon":{"lon":-1108904794,"lat":412623516}}},{"delta":{"node-LatLon":{"lon":-1108981375,"lat":412626474}}},{"delta":{"node-LatLon":{"lon":-1109056338,"lat":412638897}}},{"delta":{"node-LatLon":{"lon":-1109130675,"lat":412652858}}},{"delta":{"node-LatLon":{"lon":-1109205469,"lat":412665291}}},{"delta":{"node-LatLon":{"lon":-1109280079,"lat":412673471}}},{"delta":{"node-LatLon":{"lon":-1109353719,"lat":412680146}}},{"delta":{"node-LatLon":{"lon":-1109390798,"lat":412680579}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413074934,"long":-1107287759}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023921,"speed":23.64,"longitude":-105.0478016},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":43,"serialNumber":15472,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000085B12","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412678295,"long":-1109403156},"name":"eastbound_I80_6.26_18.29_SAT-5481DCC7_RC_EVANI80ELYMI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1109383397,"lat":412678737}}},{"delta":{"node-LatLon":{"lon":-1109363631,"lat":412678500}}},{"delta":{"node-LatLon":{"lon":-1109285083,"lat":412671839}}},{"delta":{"node-LatLon":{"lon":-1109208218,"lat":412662718}}},{"delta":{"node-LatLon":{"lon":-1109133790,"lat":412649197}}},{"delta":{"node-LatLon":{"lon":-1109059500,"lat":412635242}}},{"delta":{"node-LatLon":{"lon":-1108983731,"lat":412622770}}},{"delta":{"node-LatLon":{"lon":-1108906400,"lat":412619640}}},{"delta":{"node-LatLon":{"lon":-1108829878,"lat":412627699}}},{"delta":{"node-LatLon":{"lon":-1108756816,"lat":412646172}}},{"delta":{"node-LatLon":{"lon":-1108689511,"lat":412674500}}},{"delta":{"node-LatLon":{"lon":-1108627647,"lat":412707502}}},{"delta":{"node-LatLon":{"lon":-1108557015,"lat":412724866}}},{"delta":{"node-LatLon":{"lon":-1108485391,"lat":412706101}}},{"delta":{"node-LatLon":{"lon":-1108415692,"lat":412680645}}},{"delta":{"node-LatLon":{"lon":-1108339283,"lat":412677822}}},{"delta":{"node-LatLon":{"lon":-1108270801,"lat":412702792}}},{"delta":{"node-LatLon":{"lon":-1108202724,"lat":412728468}}},{"delta":{"node-LatLon":{"lon":-1108127111,"lat":412729008}}},{"delta":{"node-LatLon":{"lon":-1108052987,"lat":412735898}}},{"delta":{"node-LatLon":{"lon":-1107995597,"lat":412772983}}},{"delta":{"node-LatLon":{"lon":-1107941620,"lat":412814258}}},{"delta":{"node-LatLon":{"lon":-1107887900,"lat":412855724}}},{"delta":{"node-LatLon":{"lon":-1107834045,"lat":412896917}}},{"delta":{"node-LatLon":{"lon":-1107779426,"lat":412937317}}},{"delta":{"node-LatLon":{"lon":-1107716124,"lat":412969726}}},{"delta":{"node-LatLon":{"lon":-1107651938,"lat":413001633}}},{"delta":{"node-LatLon":{"lon":-1107584096,"lat":413028452}}},{"delta":{"node-LatLon":{"lon":-1107511903,"lat":413049025}}},{"delta":{"node-LatLon":{"lon":-1107439402,"lat":413069631}}},{"delta":{"node-LatLon":{"lon":-1107366103,"lat":413088130}}},{"delta":{"node-LatLon":{"lon":-1107309808,"lat":413079907}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412678295,"long":-1109403156}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023921,"speed":23.64,"longitude":-105.0478016},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":42,"serialNumber":15471,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31461,"packetID":"00000000000002B464","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412378541,"long":-1054372542},"name":"westbound_I80_317.45_323.05_SAT-DBAB5858_RC_LARI80ECHEYD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}},{"delta":{"node-LatLon":{"lon":-1054421149,"lat":412472313}}},{"delta":{"node-LatLon":{"lon":-1054429340,"lat":412485351}}},{"delta":{"node-LatLon":{"lon":-1054437555,"lat":412498379}}},{"delta":{"node-LatLon":{"lon":-1054445744,"lat":412511417}}},{"delta":{"node-LatLon":{"lon":-1054453974,"lat":412524441}}},{"delta":{"node-LatLon":{"lon":-1054463289,"lat":412537025}}},{"delta":{"node-LatLon":{"lon":-1054475122,"lat":412548474}}},{"delta":{"node-LatLon":{"lon":-1054489160,"lat":412558405}}},{"delta":{"node-LatLon":{"lon":-1054504069,"lat":412567600}}},{"delta":{"node-LatLon":{"lon":-1054519000,"lat":412576776}}},{"delta":{"node-LatLon":{"lon":-1054533896,"lat":412585985}}},{"delta":{"node-LatLon":{"lon":-1054548833,"lat":412595156}}},{"delta":{"node-LatLon":{"lon":-1054563820,"lat":412604280}}},{"delta":{"node-LatLon":{"lon":-1054579779,"lat":412612388}}},{"delta":{"node-LatLon":{"lon":-1054597055,"lat":412618777}}},{"delta":{"node-LatLon":{"lon":-1054615114,"lat":412623812}}},{"delta":{"node-LatLon":{"lon":-1054632271,"lat":412629637}}},{"delta":{"node-LatLon":{"lon":-1054647306,"lat":412638180}}},{"delta":{"node-LatLon":{"lon":-1054662004,"lat":412647078}}},{"delta":{"node-LatLon":{"lon":-1054678467,"lat":412653902}}},{"delta":{"node-LatLon":{"lon":-1054696868,"lat":412656761}}},{"delta":{"node-LatLon":{"lon":-1054715678,"lat":412657581}}},{"delta":{"node-LatLon":{"lon":-1054734355,"lat":412659287}}},{"delta":{"node-LatLon":{"lon":-1054751683,"lat":412664718}}},{"delta":{"node-LatLon":{"lon":-1054765976,"lat":412673917}}},{"delta":{"node-LatLon":{"lon":-1054778503,"lat":412684544}}},{"delta":{"node-LatLon":{"lon":-1054791379,"lat":412695492}}},{"delta":{"node-LatLon":{"lon":-1054804278,"lat":412706425}}},{"delta":{"node-LatLon":{"lon":-1054818479,"lat":412716349}}},{"delta":{"node-LatLon":{"lon":-1054835859,"lat":412722690}}},{"delta":{"node-LatLon":{"lon":-1054854996,"lat":412724695}}},{"delta":{"node-LatLon":{"lon":-1054874196,"lat":412722759}}},{"delta":{"node-LatLon":{"lon":-1054893260,"lat":412720064}}},{"delta":{"node-LatLon":{"lon":-1054912492,"lat":412718274}}},{"delta":{"node-LatLon":{"lon":-1054931875,"lat":412718613}}},{"delta":{"node-LatLon":{"lon":-1054951253,"lat":412719209}}},{"delta":{"node-LatLon":{"lon":-1054969662,"lat":412719789}}},{"delta":{"node-LatLon":{"lon":-1054987987,"lat":412721117}}},{"delta":{"node-LatLon":{"lon":-1055005745,"lat":412724757}}},{"delta":{"node-LatLon":{"lon":-1055022420,"lat":412730636}}},{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412378541,"long":-1054372542}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31461}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023878,"speed":23.64,"longitude":-105.0478293},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":41,"serialNumber":15470,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31461,"packetID":"0000000000000939DD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412846200,"long":-1055207674},"name":"eastbound_I80_317.45_323.05_SAT-85B2D861_RC_LARI80ECHEYI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055196465,"lat":412834401}}},{"delta":{"node-LatLon":{"lon":-1055185238,"lat":412822611}}},{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055162838,"lat":412799002}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055139485,"lat":412775945}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055111710,"lat":412756134}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055080126,"lat":412740115}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055046853,"lat":412726244}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1055009981,"lat":412719587}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054972006,"lat":412717639}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054934016,"lat":412716179}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054896123,"lat":412717322}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054858665,"lat":412722173}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054822378,"lat":412715508}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054795466,"lat":412695384}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054770097,"lat":412673836}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054738855,"lat":412657720}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054700821,"lat":412654615}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054664843,"lat":412645844}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054634409,"lat":412628251}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054599367,"lat":412616899}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054566302,"lat":412602767}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054536736,"lat":412584610}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054507197,"lat":412566427}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054478373,"lat":412547636}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054457123,"lat":412523979}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054440857,"lat":412498114}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054424622,"lat":412472238}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054408332,"lat":412446382}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054392109,"lat":412420501}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054379237,"lat":412393551}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412846200,"long":-1055207674}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31461}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023793,"speed":23.56,"longitude":-105.0478845},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":40,"serialNumber":15469,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31306,"packetID":"0000000000000936E7","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417414634,"long":-1068269969},"name":"westbound_I80_221.2_235.23_SAT-09D8678A_RC_RAWI80ELARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068289321,"lat":417415359}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}},{"delta":{"node-LatLon":{"lon":-1068385974,"lat":417418859}}},{"delta":{"node-LatLon":{"lon":-1068463156,"lat":417421689}}},{"delta":{"node-LatLon":{"lon":-1068540338,"lat":417424515}}},{"delta":{"node-LatLon":{"lon":-1068617852,"lat":417427395}}},{"delta":{"node-LatLon":{"lon":-1068695369,"lat":417430231}}},{"delta":{"node-LatLon":{"lon":-1068772890,"lat":417433050}}},{"delta":{"node-LatLon":{"lon":-1068850417,"lat":417435830}}},{"delta":{"node-LatLon":{"lon":-1068927943,"lat":417438632}}},{"delta":{"node-LatLon":{"lon":-1069005025,"lat":417441424}}},{"delta":{"node-LatLon":{"lon":-1069082106,"lat":417444219}}},{"delta":{"node-LatLon":{"lon":-1069159408,"lat":417446974}}},{"delta":{"node-LatLon":{"lon":-1069236759,"lat":417451306}}},{"delta":{"node-LatLon":{"lon":-1069312011,"lat":417465173}}},{"delta":{"node-LatLon":{"lon":-1069385103,"lat":417484568}}},{"delta":{"node-LatLon":{"lon":-1069458135,"lat":417504094}}},{"delta":{"node-LatLon":{"lon":-1069530060,"lat":417523167}}},{"delta":{"node-LatLon":{"lon":-1069600849,"lat":417541844}}},{"delta":{"node-LatLon":{"lon":-1069673525,"lat":417555795}}},{"delta":{"node-LatLon":{"lon":-1069748966,"lat":417568966}}},{"delta":{"node-LatLon":{"lon":-1069824418,"lat":417582109}}},{"delta":{"node-LatLon":{"lon":-1069899351,"lat":417595155}}},{"delta":{"node-LatLon":{"lon":-1069973766,"lat":417608100}}},{"delta":{"node-LatLon":{"lon":-1070048170,"lat":417621086}}},{"delta":{"node-LatLon":{"lon":-1070123773,"lat":417634264}}},{"delta":{"node-LatLon":{"lon":-1070199399,"lat":417647374}}},{"delta":{"node-LatLon":{"lon":-1070274965,"lat":417660512}}},{"delta":{"node-LatLon":{"lon":-1070350472,"lat":417673678}}},{"delta":{"node-LatLon":{"lon":-1070425989,"lat":417686813}}},{"delta":{"node-LatLon":{"lon":-1070501711,"lat":417699947}}},{"delta":{"node-LatLon":{"lon":-1070577425,"lat":417713109}}},{"delta":{"node-LatLon":{"lon":-1070653637,"lat":417726293}}},{"delta":{"node-LatLon":{"lon":-1070730992,"lat":417736504}}},{"delta":{"node-LatLon":{"lon":-1070808409,"lat":417727589}}},{"delta":{"node-LatLon":{"lon":-1070884161,"lat":417718392}}},{"delta":{"node-LatLon":{"lon":-1070959940,"lat":417729715}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417414634,"long":-1068269969}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31306}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023793,"speed":23.56,"longitude":-105.0478845},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":39,"serialNumber":15468,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31306,"packetID":"00000000000009698C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417730521,"long":-1070980675},"name":"eastbound_I80_221.2_235.23_SAT-BA88D691_RC_RAWI80ELARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1070961677,"lat":417727641}}},{"delta":{"node-LatLon":{"lon":-1070885649,"lat":417716362}}},{"delta":{"node-LatLon":{"lon":-1070809626,"lat":417725169}}},{"delta":{"node-LatLon":{"lon":-1070732756,"lat":417733042}}},{"delta":{"node-LatLon":{"lon":-1070656229,"lat":417722191}}},{"delta":{"node-LatLon":{"lon":-1070580490,"lat":417709023}}},{"delta":{"node-LatLon":{"lon":-1070504992,"lat":417695900}}},{"delta":{"node-LatLon":{"lon":-1070429493,"lat":417682786}}},{"delta":{"node-LatLon":{"lon":-1070354047,"lat":417669673}}},{"delta":{"node-LatLon":{"lon":-1070278596,"lat":417656581}}},{"delta":{"node-LatLon":{"lon":-1070202954,"lat":417643413}}},{"delta":{"node-LatLon":{"lon":-1070127097,"lat":417630244}}},{"delta":{"node-LatLon":{"lon":-1070051256,"lat":417617028}}},{"delta":{"node-LatLon":{"lon":-1069975759,"lat":417603852}}},{"delta":{"node-LatLon":{"lon":-1069900250,"lat":417590719}}},{"delta":{"node-LatLon":{"lon":-1069825529,"lat":417577695}}},{"delta":{"node-LatLon":{"lon":-1069751604,"lat":417564757}}},{"delta":{"node-LatLon":{"lon":-1069677665,"lat":417551870}}},{"delta":{"node-LatLon":{"lon":-1069603910,"lat":417538967}}},{"delta":{"node-LatLon":{"lon":-1069531945,"lat":417521380}}},{"delta":{"node-LatLon":{"lon":-1069460002,"lat":417502274}}},{"delta":{"node-LatLon":{"lon":-1069387530,"lat":417482961}}},{"delta":{"node-LatLon":{"lon":-1069315049,"lat":417463671}}},{"delta":{"node-LatLon":{"lon":-1069240161,"lat":417448143}}},{"delta":{"node-LatLon":{"lon":-1069162781,"lat":417442613}}},{"delta":{"node-LatLon":{"lon":-1069085198,"lat":417439823}}},{"delta":{"node-LatLon":{"lon":-1069007744,"lat":417437041}}},{"delta":{"node-LatLon":{"lon":-1068930291,"lat":417434237}}},{"delta":{"node-LatLon":{"lon":-1068853004,"lat":417431463}}},{"delta":{"node-LatLon":{"lon":-1068775721,"lat":417428637}}},{"delta":{"node-LatLon":{"lon":-1068698384,"lat":417425830}}},{"delta":{"node-LatLon":{"lon":-1068620993,"lat":417423054}}},{"delta":{"node-LatLon":{"lon":-1068543604,"lat":417420239}}},{"delta":{"node-LatLon":{"lon":-1068465827,"lat":417417448}}},{"delta":{"node-LatLon":{"lon":-1068388058,"lat":417414571}}},{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068291290,"lat":417411033}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417730521,"long":-1070980675}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31306}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023754,"speed":23.44,"longitude":-105.047912},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":38,"serialNumber":15467,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"0000000000000CAD04","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417236030,"long":-1064577050},"name":"westbound_I80_235.23_255.6_SAT-5249C81B_RC_EMI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}},{"delta":{"node-LatLon":{"lon":-1064663938,"lat":417268988}}},{"delta":{"node-LatLon":{"lon":-1064732992,"lat":417295169}}},{"delta":{"node-LatLon":{"lon":-1064801593,"lat":417321158}}},{"delta":{"node-LatLon":{"lon":-1064868982,"lat":417348724}}},{"delta":{"node-LatLon":{"lon":-1064918112,"lat":417392970}}},{"delta":{"node-LatLon":{"lon":-1064954285,"lat":417444108}}},{"delta":{"node-LatLon":{"lon":-1065013176,"lat":417481407}}},{"delta":{"node-LatLon":{"lon":-1065076232,"lat":417514937}}},{"delta":{"node-LatLon":{"lon":-1065143647,"lat":417541998}}},{"delta":{"node-LatLon":{"lon":-1065216141,"lat":417525688}}},{"delta":{"node-LatLon":{"lon":-1065286224,"lat":417501265}}},{"delta":{"node-LatLon":{"lon":-1065362113,"lat":417489852}}},{"delta":{"node-LatLon":{"lon":-1065436335,"lat":417474443}}},{"delta":{"node-LatLon":{"lon":-1065509545,"lat":417456289}}},{"delta":{"node-LatLon":{"lon":-1065583202,"lat":417438150}}},{"delta":{"node-LatLon":{"lon":-1065656809,"lat":417419903}}},{"delta":{"node-LatLon":{"lon":-1065731883,"lat":417405563}}},{"delta":{"node-LatLon":{"lon":-1065807502,"lat":417392751}}},{"delta":{"node-LatLon":{"lon":-1065883116,"lat":417379926}}},{"delta":{"node-LatLon":{"lon":-1065957863,"lat":417367400}}},{"delta":{"node-LatLon":{"lon":-1066034015,"lat":417367499}}},{"delta":{"node-LatLon":{"lon":-1066107964,"lat":417383273}}},{"delta":{"node-LatLon":{"lon":-1066182713,"lat":417397479}}},{"delta":{"node-LatLon":{"lon":-1066259373,"lat":417393785}}},{"delta":{"node-LatLon":{"lon":-1066332961,"lat":417375298}}},{"delta":{"node-LatLon":{"lon":-1066406270,"lat":417356150}}},{"delta":{"node-LatLon":{"lon":-1066479386,"lat":417336915}}},{"delta":{"node-LatLon":{"lon":-1066552888,"lat":417319016}}},{"delta":{"node-LatLon":{"lon":-1066629919,"lat":417314788}}},{"delta":{"node-LatLon":{"lon":-1066707699,"lat":417312949}}},{"delta":{"node-LatLon":{"lon":-1066785479,"lat":417311107}}},{"delta":{"node-LatLon":{"lon":-1066862945,"lat":417309275}}},{"delta":{"node-LatLon":{"lon":-1066940095,"lat":417307413}}},{"delta":{"node-LatLon":{"lon":-1067017196,"lat":417307583}}},{"delta":{"node-LatLon":{"lon":-1067093337,"lat":417317382}}},{"delta":{"node-LatLon":{"lon":-1067169430,"lat":417327402}}},{"delta":{"node-LatLon":{"lon":-1067245652,"lat":417337364}}},{"delta":{"node-LatLon":{"lon":-1067321980,"lat":417347366}}},{"delta":{"node-LatLon":{"lon":-1067398306,"lat":417357382}}},{"delta":{"node-LatLon":{"lon":-1067473287,"lat":417371223}}},{"delta":{"node-LatLon":{"lon":-1067545644,"lat":417391873}}},{"delta":{"node-LatLon":{"lon":-1067618034,"lat":417412485}}},{"delta":{"node-LatLon":{"lon":-1067691111,"lat":417431502}}},{"delta":{"node-LatLon":{"lon":-1067768403,"lat":417431260}}},{"delta":{"node-LatLon":{"lon":-1067845690,"lat":417428509}}},{"delta":{"node-LatLon":{"lon":-1067922977,"lat":417425763}}},{"delta":{"node-LatLon":{"lon":-1068000058,"lat":417422940}}},{"delta":{"node-LatLon":{"lon":-1068076949,"lat":417420295}}},{"delta":{"node-LatLon":{"lon":-1068153829,"lat":417417471}}},{"delta":{"node-LatLon":{"lon":-1068231245,"lat":417414693}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417236030,"long":-1064577050}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023754,"speed":23.44,"longitude":-105.047912},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":37,"serialNumber":15466,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.853Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"0000000000000B72CD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417412478,"long":-1068329876},"name":"eastbound_I80_235.23_255.6_SAT-BC6CCC19_RC_EMI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068233386,"lat":417410283}}},{"delta":{"node-LatLon":{"lon":-1068156206,"lat":417413060}}},{"delta":{"node-LatLon":{"lon":-1068078777,"lat":417415820}}},{"delta":{"node-LatLon":{"lon":-1068001349,"lat":417418584}}},{"delta":{"node-LatLon":{"lon":-1067924043,"lat":417421374}}},{"delta":{"node-LatLon":{"lon":-1067846854,"lat":417424119}}},{"delta":{"node-LatLon":{"lon":-1067769664,"lat":417426862}}},{"delta":{"node-LatLon":{"lon":-1067693191,"lat":417427429}}},{"delta":{"node-LatLon":{"lon":-1067620890,"lat":417408658}}},{"delta":{"node-LatLon":{"lon":-1067548859,"lat":417388122}}},{"delta":{"node-LatLon":{"lon":-1067476428,"lat":417367444}}},{"delta":{"node-LatLon":{"lon":-1067401438,"lat":417353366}}},{"delta":{"node-LatLon":{"lon":-1067324763,"lat":417343330}}},{"delta":{"node-LatLon":{"lon":-1067248094,"lat":417333277}}},{"delta":{"node-LatLon":{"lon":-1067171506,"lat":417323258}}},{"delta":{"node-LatLon":{"lon":-1067095014,"lat":417313213}}},{"delta":{"node-LatLon":{"lon":-1067018343,"lat":417304140}}},{"delta":{"node-LatLon":{"lon":-1066941341,"lat":417305018}}},{"delta":{"node-LatLon":{"lon":-1066864327,"lat":417306535}}},{"delta":{"node-LatLon":{"lon":-1066786982,"lat":417308392}}},{"delta":{"node-LatLon":{"lon":-1066709294,"lat":417310231}}},{"delta":{"node-LatLon":{"lon":-1066631604,"lat":417312052}}},{"delta":{"node-LatLon":{"lon":-1066553905,"lat":417315567}}},{"delta":{"node-LatLon":{"lon":-1066479234,"lat":417331977}}},{"delta":{"node-LatLon":{"lon":-1066405938,"lat":417350968}}},{"delta":{"node-LatLon":{"lon":-1066333222,"lat":417370336}}},{"delta":{"node-LatLon":{"lon":-1066260210,"lat":417389047}}},{"delta":{"node-LatLon":{"lon":-1066185059,"lat":417393215}}},{"delta":{"node-LatLon":{"lon":-1066111705,"lat":417379368}}},{"delta":{"node-LatLon":{"lon":-1066037468,"lat":417363405}}},{"delta":{"node-LatLon":{"lon":-1065959182,"lat":417362605}}},{"delta":{"node-LatLon":{"lon":-1065882330,"lat":417375426}}},{"delta":{"node-LatLon":{"lon":-1065806758,"lat":417388216}}},{"delta":{"node-LatLon":{"lon":-1065731194,"lat":417401042}}},{"delta":{"node-LatLon":{"lon":-1065656118,"lat":417415246}}},{"delta":{"node-LatLon":{"lon":-1065582542,"lat":417433443}}},{"delta":{"node-LatLon":{"lon":-1065508992,"lat":417451702}}},{"delta":{"node-LatLon":{"lon":-1065434680,"lat":417470091}}},{"delta":{"node-LatLon":{"lon":-1065359330,"lat":417485637}}},{"delta":{"node-LatLon":{"lon":-1065283762,"lat":417497543}}},{"delta":{"node-LatLon":{"lon":-1065215939,"lat":417523097}}},{"delta":{"node-LatLon":{"lon":-1065145106,"lat":417539870}}},{"delta":{"node-LatLon":{"lon":-1065078198,"lat":417513374}}},{"delta":{"node-LatLon":{"lon":-1065015853,"lat":417480011}}},{"delta":{"node-LatLon":{"lon":-1064958078,"lat":417441842}}},{"delta":{"node-LatLon":{"lon":-1064922715,"lat":417389692}}},{"delta":{"node-LatLon":{"lon":-1064872664,"lat":417345234}}},{"delta":{"node-LatLon":{"lon":-1064805541,"lat":417317528}}},{"delta":{"node-LatLon":{"lon":-1064737065,"lat":417291583}}},{"delta":{"node-LatLon":{"lon":-1064668140,"lat":417265497}}},{"delta":{"node-LatLon":{"lon":-1064598834,"lat":417239175}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417412478,"long":-1068329876}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023629,"speed":23.16,"longitude":-105.0479939},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":32,"serialNumber":15461,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000EF64E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415981013,"long":-1062070609},"name":"westbound_I80_267.19_272.06_SAT-1F82D7A2_RC_ARLI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062090421,"lat":415980971}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062129021,"lat":415980789}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415981013,"long":-1062070609}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":54}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023711,"speed":23.16,"longitude":-105.0479398},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":36,"serialNumber":15465,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.753Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"000000000000097BE1","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416329581,"long":-1062818144},"name":"westbound_I80_255.6_267.19_SAT-EF31CF04_RC_EMI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062861444,"lat":416357241}}},{"delta":{"node-LatLon":{"lon":-1062891617,"lat":416376465}}},{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062961089,"lat":416403834}}},{"delta":{"node-LatLon":{"lon":-1062999651,"lat":416410539}}},{"delta":{"node-LatLon":{"lon":-1063038256,"lat":416417110}}},{"delta":{"node-LatLon":{"lon":-1063075838,"lat":416423525}}},{"delta":{"node-LatLon":{"lon":-1063113422,"lat":416429935}}},{"delta":{"node-LatLon":{"lon":-1063151010,"lat":416436333}}},{"delta":{"node-LatLon":{"lon":-1063187758,"lat":416444929}}},{"delta":{"node-LatLon":{"lon":-1063221748,"lat":416458478}}},{"delta":{"node-LatLon":{"lon":-1063254248,"lat":416474223}}},{"delta":{"node-LatLon":{"lon":-1063286767,"lat":416489947}}},{"delta":{"node-LatLon":{"lon":-1063319286,"lat":416505671}}},{"delta":{"node-LatLon":{"lon":-1063351803,"lat":416521398}}},{"delta":{"node-LatLon":{"lon":-1063384308,"lat":416537141}}},{"delta":{"node-LatLon":{"lon":-1063416537,"lat":416552741}}},{"delta":{"node-LatLon":{"lon":-1063448756,"lat":416568353}}},{"delta":{"node-LatLon":{"lon":-1063480997,"lat":416583940}}},{"delta":{"node-LatLon":{"lon":-1063513230,"lat":416599539}}},{"delta":{"node-LatLon":{"lon":-1063545479,"lat":416615118}}},{"delta":{"node-LatLon":{"lon":-1063577703,"lat":416630746}}},{"delta":{"node-LatLon":{"lon":-1063609979,"lat":416646315}}},{"delta":{"node-LatLon":{"lon":-1063642246,"lat":416661894}}},{"delta":{"node-LatLon":{"lon":-1063674320,"lat":416677693}}},{"delta":{"node-LatLon":{"lon":-1063702475,"lat":416697159}}},{"delta":{"node-LatLon":{"lon":-1063724503,"lat":416721905}}},{"delta":{"node-LatLon":{"lon":-1063738013,"lat":416749885}}},{"delta":{"node-LatLon":{"lon":-1063745688,"lat":416779149}}},{"delta":{"node-LatLon":{"lon":-1063757512,"lat":416807580}}},{"delta":{"node-LatLon":{"lon":-1063775542,"lat":416834147}}},{"delta":{"node-LatLon":{"lon":-1063793398,"lat":416858977}}},{"delta":{"node-LatLon":{"lon":-1063809837,"lat":416884350}}},{"delta":{"node-LatLon":{"lon":-1063824918,"lat":416910195}}},{"delta":{"node-LatLon":{"lon":-1063839847,"lat":416936091}}},{"delta":{"node-LatLon":{"lon":-1063856289,"lat":416961436}}},{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063910309,"lat":417002755}}},{"delta":{"node-LatLon":{"lon":-1063944810,"lat":417016237}}},{"delta":{"node-LatLon":{"lon":-1063979929,"lat":417028841}}},{"delta":{"node-LatLon":{"lon":-1064015050,"lat":417041442}}},{"delta":{"node-LatLon":{"lon":-1064050617,"lat":417052787}}},{"delta":{"node-LatLon":{"lon":-1064088491,"lat":417058422}}},{"delta":{"node-LatLon":{"lon":-1064127128,"lat":417059995}}},{"delta":{"node-LatLon":{"lon":-1064165769,"lat":417061539}}},{"delta":{"node-LatLon":{"lon":-1064204408,"lat":417063119}}},{"delta":{"node-LatLon":{"lon":-1064242489,"lat":417067748}}},{"delta":{"node-LatLon":{"lon":-1064278067,"lat":417078928}}},{"delta":{"node-LatLon":{"lon":-1064309216,"lat":417095993}}},{"delta":{"node-LatLon":{"lon":-1064338068,"lat":417115288}}},{"delta":{"node-LatLon":{"lon":-1064366996,"lat":417134521}}},{"delta":{"node-LatLon":{"lon":-1064396523,"lat":417152988}}},{"delta":{"node-LatLon":{"lon":-1064427177,"lat":417170394}}},{"delta":{"node-LatLon":{"lon":-1064458838,"lat":417186756}}},{"delta":{"node-LatLon":{"lon":-1064491487,"lat":417201990}}},{"delta":{"node-LatLon":{"lon":-1064525046,"lat":417216068}}},{"delta":{"node-LatLon":{"lon":-1064559666,"lat":417229448}}},{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416329581,"long":-1062818144}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023629,"speed":23.16,"longitude":-105.0479939},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":33,"serialNumber":15462,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.653Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"00000000000010847D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415976300,"long":-1062132565},"name":"eastbound_I80_272.06_279.86_SAT-A456B6BD_RC_ARLI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060830479,"lat":415423609}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415976300,"long":-1062132565}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":36}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.102367,"speed":23.16,"longitude":-105.0479669},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":35,"serialNumber":15464,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.753Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"000000000000043991","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417245737,"long":-1064616173},"name":"eastbound_I80_255.6_267.19_SAT-9BEE74D0_RC_EMI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1064598834,"lat":417239175}}},{"delta":{"node-LatLon":{"lon":-1064564140,"lat":417226077}}},{"delta":{"node-LatLon":{"lon":-1064529505,"lat":417212891}}},{"delta":{"node-LatLon":{"lon":-1064496024,"lat":417198853}}},{"delta":{"node-LatLon":{"lon":-1064463440,"lat":417183676}}},{"delta":{"node-LatLon":{"lon":-1064431804,"lat":417167410}}},{"delta":{"node-LatLon":{"lon":-1064401163,"lat":417150110}}},{"delta":{"node-LatLon":{"lon":-1064371651,"lat":417131742}}},{"delta":{"node-LatLon":{"lon":-1064342280,"lat":417112106}}},{"delta":{"node-LatLon":{"lon":-1064312928,"lat":417092456}}},{"delta":{"node-LatLon":{"lon":-1064281084,"lat":417075243}}},{"delta":{"node-LatLon":{"lon":-1064244933,"lat":417063737}}},{"delta":{"node-LatLon":{"lon":-1064206236,"lat":417058710}}},{"delta":{"node-LatLon":{"lon":-1064168081,"lat":417057202}}},{"delta":{"node-LatLon":{"lon":-1064129929,"lat":417055664}}},{"delta":{"node-LatLon":{"lon":-1064091774,"lat":417054155}}},{"delta":{"node-LatLon":{"lon":-1064054270,"lat":417049080}}},{"delta":{"node-LatLon":{"lon":-1064019101,"lat":417037984}}},{"delta":{"node-LatLon":{"lon":-1063985061,"lat":417025732}}},{"delta":{"node-LatLon":{"lon":-1063951019,"lat":417013482}}},{"delta":{"node-LatLon":{"lon":-1063917284,"lat":417000788}}},{"delta":{"node-LatLon":{"lon":-1063887416,"lat":416983573}}},{"delta":{"node-LatLon":{"lon":-1063863549,"lat":416961722}}},{"delta":{"node-LatLon":{"lon":-1063846461,"lat":416936273}}},{"delta":{"node-LatLon":{"lon":-1063831379,"lat":416910073}}},{"delta":{"node-LatLon":{"lon":-1063816138,"lat":416883925}}},{"delta":{"node-LatLon":{"lon":-1063799617,"lat":416858220}}},{"delta":{"node-LatLon":{"lon":-1063781616,"lat":416833080}}},{"delta":{"node-LatLon":{"lon":-1063763325,"lat":416806477}}},{"delta":{"node-LatLon":{"lon":-1063751513,"lat":416777919}}},{"delta":{"node-LatLon":{"lon":-1063743848,"lat":416748530}}},{"delta":{"node-LatLon":{"lon":-1063730315,"lat":416720424}}},{"delta":{"node-LatLon":{"lon":-1063708354,"lat":416695491}}},{"delta":{"node-LatLon":{"lon":-1063680444,"lat":416675556}}},{"delta":{"node-LatLon":{"lon":-1063648291,"lat":416659518}}},{"delta":{"node-LatLon":{"lon":-1063615844,"lat":416643807}}},{"delta":{"node-LatLon":{"lon":-1063583366,"lat":416628132}}},{"delta":{"node-LatLon":{"lon":-1063550917,"lat":416612423}}},{"delta":{"node-LatLon":{"lon":-1063518397,"lat":416596725}}},{"delta":{"node-LatLon":{"lon":-1063485899,"lat":416581001}}},{"delta":{"node-LatLon":{"lon":-1063453403,"lat":416565276}}},{"delta":{"node-LatLon":{"lon":-1063420938,"lat":416549517}}},{"delta":{"node-LatLon":{"lon":-1063388402,"lat":416533840}}},{"delta":{"node-LatLon":{"lon":-1063355954,"lat":416518111}}},{"delta":{"node-LatLon":{"lon":-1063323497,"lat":416502393}}},{"delta":{"node-LatLon":{"lon":-1063291009,"lat":416486712}}},{"delta":{"node-LatLon":{"lon":-1063258568,"lat":416470977}}},{"delta":{"node-LatLon":{"lon":-1063226121,"lat":416455250}}},{"delta":{"node-LatLon":{"lon":-1063191824,"lat":416441408}}},{"delta":{"node-LatLon":{"lon":-1063154787,"lat":416432390}}},{"delta":{"node-LatLon":{"lon":-1063116772,"lat":416425883}}},{"delta":{"node-LatLon":{"lon":-1063078751,"lat":416419398}}},{"delta":{"node-LatLon":{"lon":-1063040728,"lat":416412924}}},{"delta":{"node-LatLon":{"lon":-1063002941,"lat":416406471}}},{"delta":{"node-LatLon":{"lon":-1062965166,"lat":416399984}}},{"delta":{"node-LatLon":{"lon":-1062928900,"lat":416389943}}},{"delta":{"node-LatLon":{"lon":-1062896756,"lat":416373819}}},{"delta":{"node-LatLon":{"lon":-1062867209,"lat":416355008}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417245737,"long":-1064616173}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.102367,"speed":23.16,"longitude":-105.0479669},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":34,"serialNumber":15463,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.653Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000C4306","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415413487,"long":-1060812632},"name":"westbound_I80_272.06_279.86_SAT-84FB2473_RC_ARLI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060824406,"lat":415424958}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415413487,"long":-1060812632}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":48}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":28,"serialNumber":15457,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31584,"packetID":"0000000000000C776A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412012058,"long":-1054342550},"name":"westbound_I80_325.78_322.6_SAT-1A7FD750_VSL_V002148","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054353231,"lat":412023546}}},{"delta":{"node-LatLon":{"lon":-1054363915,"lat":412035033}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054384730,"lat":412058284}}},{"delta":{"node-LatLon":{"lon":-1054393246,"lat":412070758}}},{"delta":{"node-LatLon":{"lon":-1054401396,"lat":412083376}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054411451,"lat":412110222}}},{"delta":{"node-LatLon":{"lon":-1054410494,"lat":412124215}}},{"delta":{"node-LatLon":{"lon":-1054406258,"lat":412138313}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054396763,"lat":412166333}}},{"delta":{"node-LatLon":{"lon":-1054391999,"lat":412180340}}},{"delta":{"node-LatLon":{"lon":-1054387248,"lat":412194350}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054380050,"lat":412222697}}},{"delta":{"node-LatLon":{"lon":-1054380942,"lat":412237122}}},{"delta":{"node-LatLon":{"lon":-1054384055,"lat":412251390}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054387713,"lat":412280108}}},{"delta":{"node-LatLon":{"lon":-1054383702,"lat":412294247}}},{"delta":{"node-LatLon":{"lon":-1054376516,"lat":412307678}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054366196,"lat":412335412}}},{"delta":{"node-LatLon":{"lon":-1054366933,"lat":412349870}}},{"delta":{"node-LatLon":{"lon":-1054369671,"lat":412364212}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000000011}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412012058,"long":-1054342550}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31584}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":31,"serialNumber":15460,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000EA327","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416355008,"long":-1062867209},"name":"eastbound_I80_267.19_272.06_SAT-7ECE7CF3_RC_ARLI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062727519,"lat":416279817}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062690294,"lat":416271928}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062652620,"lat":416264564}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062614940,"lat":416257216}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062577255,"lat":416249886}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062539573,"lat":416242549}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062501815,"lat":416235141}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062464244,"lat":416227007}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062429289,"lat":416213939}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062398699,"lat":416195722}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062373783,"lat":416173151}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062353839,"lat":416148895}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062334576,"lat":416125335}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062315283,"lat":416101788}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062296038,"lat":416078220}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062276808,"lat":416054645}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062257093,"lat":416030536}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062236012,"lat":416006340}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062206968,"lat":415987559}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062171008,"lat":415977603}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062132565,"lat":415976300}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062093782,"lat":415976349}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416355008,"long":-1062867209}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":30,"serialNumber":15459,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31410,"packetID":"000000000000052CAD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416762809,"long":-1079776048},"name":"westbound_I80_158.55_173.41_SAT-53B47E1D_RC_WAMI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1079792654,"lat":416755214}}},{"delta":{"node-LatLon":{"lon":-1079842491,"lat":416732454}}},{"delta":{"node-LatLon":{"lon":-1079913673,"lat":416710891}}},{"delta":{"node-LatLon":{"lon":-1079988998,"lat":416700558}}},{"delta":{"node-LatLon":{"lon":-1080064380,"lat":416690465}}},{"delta":{"node-LatLon":{"lon":-1080140410,"lat":416680262}}},{"delta":{"node-LatLon":{"lon":-1080216433,"lat":416670036}}},{"delta":{"node-LatLon":{"lon":-1080292501,"lat":416659806}}},{"delta":{"node-LatLon":{"lon":-1080368608,"lat":416649545}}},{"delta":{"node-LatLon":{"lon":-1080444725,"lat":416639329}}},{"delta":{"node-LatLon":{"lon":-1080520774,"lat":416629083}}},{"delta":{"node-LatLon":{"lon":-1080596810,"lat":416618789}}},{"delta":{"node-LatLon":{"lon":-1080672394,"lat":416608577}}},{"delta":{"node-LatLon":{"lon":-1080747529,"lat":416598458}}},{"delta":{"node-LatLon":{"lon":-1080822654,"lat":416588304}}},{"delta":{"node-LatLon":{"lon":-1080898633,"lat":416578054}}},{"delta":{"node-LatLon":{"lon":-1080974597,"lat":416567750}}},{"delta":{"node-LatLon":{"lon":-1081050829,"lat":416557420}}},{"delta":{"node-LatLon":{"lon":-1081127325,"lat":416547044}}},{"delta":{"node-LatLon":{"lon":-1081203413,"lat":416535198}}},{"delta":{"node-LatLon":{"lon":-1081277846,"lat":416519549}}},{"delta":{"node-LatLon":{"lon":-1081352245,"lat":416503811}}},{"delta":{"node-LatLon":{"lon":-1081426652,"lat":416488040}}},{"delta":{"node-LatLon":{"lon":-1081501076,"lat":416472261}}},{"delta":{"node-LatLon":{"lon":-1081575983,"lat":416457952}}},{"delta":{"node-LatLon":{"lon":-1081652109,"lat":416449993}}},{"delta":{"node-LatLon":{"lon":-1081728290,"lat":416442318}}},{"delta":{"node-LatLon":{"lon":-1081805260,"lat":416434541}}},{"delta":{"node-LatLon":{"lon":-1081883037,"lat":416426768}}},{"delta":{"node-LatLon":{"lon":-1081960802,"lat":416418934}}},{"delta":{"node-LatLon":{"lon":-1082036873,"lat":416411275}}},{"delta":{"node-LatLon":{"lon":-1082112938,"lat":416403591}}},{"delta":{"node-LatLon":{"lon":-1082188943,"lat":416395924}}},{"delta":{"node-LatLon":{"lon":-1082264890,"lat":416388279}}},{"delta":{"node-LatLon":{"lon":-1082340832,"lat":416380614}}},{"delta":{"node-LatLon":{"lon":-1082416741,"lat":416370373}}},{"delta":{"node-LatLon":{"lon":-1082492308,"lat":416358699}}},{"delta":{"node-LatLon":{"lon":-1082567978,"lat":416347001}}},{"delta":{"node-LatLon":{"lon":-1082624827,"lat":416338280}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000110000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416762809,"long":-1079776048}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31410}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":29,"serialNumber":15458,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31410,"packetID":"00000000000006E136","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416331711,"long":-1082645377},"name":"eastbound_I80_158.55_173.41_SAT-C560983B_RC_WAMI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082626530,"lat":416334663}}},{"delta":{"node-LatLon":{"lon":-1082569940,"lat":416343338}}},{"delta":{"node-LatLon":{"lon":-1082494293,"lat":416355057}}},{"delta":{"node-LatLon":{"lon":-1082418408,"lat":416366766}}},{"delta":{"node-LatLon":{"lon":-1082342222,"lat":416377204}}},{"delta":{"node-LatLon":{"lon":-1082266189,"lat":416384835}}},{"delta":{"node-LatLon":{"lon":-1082190159,"lat":416392484}}},{"delta":{"node-LatLon":{"lon":-1082114130,"lat":416400151}}},{"delta":{"node-LatLon":{"lon":-1082038109,"lat":416407878}}},{"delta":{"node-LatLon":{"lon":-1081962071,"lat":416415513}}},{"delta":{"node-LatLon":{"lon":-1081884585,"lat":416423333}}},{"delta":{"node-LatLon":{"lon":-1081807099,"lat":416431159}}},{"delta":{"node-LatLon":{"lon":-1081730361,"lat":416438843}}},{"delta":{"node-LatLon":{"lon":-1081654390,"lat":416446481}}},{"delta":{"node-LatLon":{"lon":-1081578471,"lat":416454403}}},{"delta":{"node-LatLon":{"lon":-1081503389,"lat":416468376}}},{"delta":{"node-LatLon":{"lon":-1081428908,"lat":416484193}}},{"delta":{"node-LatLon":{"lon":-1081354605,"lat":416499942}}},{"delta":{"node-LatLon":{"lon":-1081280498,"lat":416515672}}},{"delta":{"node-LatLon":{"lon":-1081206345,"lat":416531284}}},{"delta":{"node-LatLon":{"lon":-1081130243,"lat":416543380}}},{"delta":{"node-LatLon":{"lon":-1081053650,"lat":416553747}}},{"delta":{"node-LatLon":{"lon":-1080977254,"lat":416564119}}},{"delta":{"node-LatLon":{"lon":-1080901037,"lat":416574429}}},{"delta":{"node-LatLon":{"lon":-1080824822,"lat":416584754}}},{"delta":{"node-LatLon":{"lon":-1080749783,"lat":416594899}}},{"delta":{"node-LatLon":{"lon":-1080674747,"lat":416605063}}},{"delta":{"node-LatLon":{"lon":-1080599110,"lat":416615260}}},{"delta":{"node-LatLon":{"lon":-1080522881,"lat":416625527}}},{"delta":{"node-LatLon":{"lon":-1080446654,"lat":416635808}}},{"delta":{"node-LatLon":{"lon":-1080370892,"lat":416645963}}},{"delta":{"node-LatLon":{"lon":-1080295134,"lat":416656136}}},{"delta":{"node-LatLon":{"lon":-1080219094,"lat":416666380}}},{"delta":{"node-LatLon":{"lon":-1080142771,"lat":416676687}}},{"delta":{"node-LatLon":{"lon":-1080066436,"lat":416686950}}},{"delta":{"node-LatLon":{"lon":-1079990643,"lat":416697179}}},{"delta":{"node-LatLon":{"lon":-1079914851,"lat":416707417}}},{"delta":{"node-LatLon":{"lon":-1079842371,"lat":416727176}}},{"delta":{"node-LatLon":{"lon":-1079792300,"lat":416749998}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416331711,"long":-1082645377}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31410}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023509,"speed":22.96,"longitude":-105.048075},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":27,"serialNumber":15456,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"0000000000000974CF","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411380266,"long":-1053516546},"name":"westbound_I80_332.29_328.74_SAT-33F06F41_VSL_V002179","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053530152,"lat":411390760}}},{"delta":{"node-LatLon":{"lon":-1053544178,"lat":411400926}}},{"delta":{"node-LatLon":{"lon":-1053559400,"lat":411410052}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053593540,"lat":411425178}}},{"delta":{"node-LatLon":{"lon":-1053612259,"lat":411430899}}},{"delta":{"node-LatLon":{"lon":-1053631611,"lat":411435251}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053671518,"lat":411439715}}},{"delta":{"node-LatLon":{"lon":-1053691660,"lat":411440843}}},{"delta":{"node-LatLon":{"lon":-1053711798,"lat":411442014}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053751386,"lat":411447856}}},{"delta":{"node-LatLon":{"lon":-1053770441,"lat":411452906}}},{"delta":{"node-LatLon":{"lon":-1053788278,"lat":411458052}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053823914,"lat":411468418}}},{"delta":{"node-LatLon":{"lon":-1053841210,"lat":411474512}}},{"delta":{"node-LatLon":{"lon":-1053857700,"lat":411481776}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053889263,"lat":411498027}}},{"delta":{"node-LatLon":{"lon":-1053905019,"lat":411506182}}},{"delta":{"node-LatLon":{"lon":-1053920800,"lat":411514309}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053951905,"lat":411530400}}},{"delta":{"node-LatLon":{"lon":-1053967181,"lat":411538416}}},{"delta":{"node-LatLon":{"lon":-1053982070,"lat":411546836}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054010245,"lat":411565176}}},{"delta":{"node-LatLon":{"lon":-1054023504,"lat":411575034}}},{"delta":{"node-LatLon":{"lon":-1054036337,"lat":411585207}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054059788,"lat":411607021}}},{"delta":{"node-LatLon":{"lon":-1054070551,"lat":411618485}}},{"delta":{"node-LatLon":{"lon":-1054080907,"lat":411630774}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054099821,"lat":411656166}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411380266,"long":-1053516546}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023509,"speed":22.96,"longitude":-105.048075},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":26,"serialNumber":15455,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31529,"packetID":"000000000000067287","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411261912,"long":-1053190756},"name":"westbound_I80_334.3_332.29_SAT-7CB2A0D8_VSL_V002205","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053209808,"lat":411263198}}},{"delta":{"node-LatLon":{"lon":-1053228859,"lat":411264489}}},{"delta":{"node-LatLon":{"lon":-1053247874,"lat":411266056}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053284753,"lat":411270823}}},{"delta":{"node-LatLon":{"lon":-1053302624,"lat":411273801}}},{"delta":{"node-LatLon":{"lon":-1053320485,"lat":411276816}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053356049,"lat":411283332}}},{"delta":{"node-LatLon":{"lon":-1053373293,"lat":411287955}}},{"delta":{"node-LatLon":{"lon":-1053389921,"lat":411293728}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053420870,"lat":411308448}}},{"delta":{"node-LatLon":{"lon":-1053434927,"lat":411317306}}},{"delta":{"node-LatLon":{"lon":-1053448810,"lat":411327586}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053475910,"lat":411348654}}},{"delta":{"node-LatLon":{"lon":-1053489459,"lat":411359188}}},{"delta":{"node-LatLon":{"lon":-1053503009,"lat":411369723}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053530152,"lat":411390760}}},{"delta":{"node-LatLon":{"lon":-1053544178,"lat":411400926}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411261912,"long":-1053190756}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31529}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023469,"speed":22.96,"longitude":-105.0481018},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":25,"serialNumber":15454,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.152Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"000000000000021245","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412730636,"long":-1055022420},"name":"westbound_I80_318.5_316.0_SAT-A649856C_VSL_V003668","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}},{"delta":{"node-LatLon":{"lon":-1055205033,"lat":412846820}}},{"delta":{"node-LatLon":{"lon":-1055216089,"lat":412858504}}},{"delta":{"node-LatLon":{"lon":-1055227100,"lat":412870211}}},{"delta":{"node-LatLon":{"lon":-1055238096,"lat":412881927}}},{"delta":{"node-LatLon":{"lon":-1055249775,"lat":412893620}}},{"delta":{"node-LatLon":{"lon":-1055264147,"lat":412903395}}},{"delta":{"node-LatLon":{"lon":-1055281500,"lat":412909856}}},{"delta":{"node-LatLon":{"lon":-1055300530,"lat":412912497}}},{"delta":{"node-LatLon":{"lon":-1055319936,"lat":412912720}}},{"delta":{"node-LatLon":{"lon":-1055339348,"lat":412912757}}},{"delta":{"node-LatLon":{"lon":-1055358760,"lat":412912763}}},{"delta":{"node-LatLon":{"lon":-1055378172,"lat":412912749}}},{"delta":{"node-LatLon":{"lon":-1055397583,"lat":412912794}}},{"delta":{"node-LatLon":{"lon":-1055416995,"lat":412912799}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412730636,"long":-1055022420}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.8,"latitude":41.1023428,"speed":22.84,"longitude":-105.0481287},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":24,"serialNumber":15453,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.152Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31529,"packetID":"000000000000074F73","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411295468,"long":-1053412343},"name":"eastbound_I80_333.32_336.16_SAT-04EA5301_VSL_V002192","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053397283,"lat":411286440}}},{"delta":{"node-LatLon":{"lon":-1053381215,"lat":411278476}}},{"delta":{"node-LatLon":{"lon":-1053364267,"lat":411271631}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053328222,"lat":411261661}}},{"delta":{"node-LatLon":{"lon":-1053309440,"lat":411258607}}},{"delta":{"node-LatLon":{"lon":-1053290366,"lat":411256889}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053252031,"lat":411256011}}},{"delta":{"node-LatLon":{"lon":-1053232894,"lat":411255714}}},{"delta":{"node-LatLon":{"lon":-1053213757,"lat":411255411}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053175485,"lat":411254779}}},{"delta":{"node-LatLon":{"lon":-1053156349,"lat":411254454}}},{"delta":{"node-LatLon":{"lon":-1053137212,"lat":411254156}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053098943,"lat":411253445}}},{"delta":{"node-LatLon":{"lon":-1053079915,"lat":411251929}}},{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1053023237,"lat":411244960}}},{"delta":{"node-LatLon":{"lon":-1053004357,"lat":411242579}}},{"delta":{"node-LatLon":{"lon":-1052985469,"lat":411240234}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052948155,"lat":411233869}}},{"delta":{"node-LatLon":{"lon":-1052930037,"lat":411229208}}},{"delta":{"node-LatLon":{"lon":-1052912393,"lat":411223601}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052878140,"lat":411209333}}},{"delta":{"node-LatLon":{"lon":-1052861535,"lat":411200909}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411295468,"long":-1053412343}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31529}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.8,"latitude":41.1023428,"speed":22.84,"longitude":-105.0481287},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":23,"serialNumber":15452,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"0000000000000C3025","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411544031,"long":-1053986991},"name":"eastbound_I80_329.88_333.32_SAT-B0A8A48A_VSL_V002170","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053971893,"lat":411535445}}},{"delta":{"node-LatLon":{"lon":-1053956403,"lat":411527267}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053925020,"lat":411511050}}},{"delta":{"node-LatLon":{"lon":-1053909255,"lat":411502872}}},{"delta":{"node-LatLon":{"lon":-1053893491,"lat":411494693}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053861842,"lat":411478470}}},{"delta":{"node-LatLon":{"lon":-1053845388,"lat":411471122}}},{"delta":{"node-LatLon":{"lon":-1053828169,"lat":411464855}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053792523,"lat":411454408}}},{"delta":{"node-LatLon":{"lon":-1053774674,"lat":411449233}}},{"delta":{"node-LatLon":{"lon":-1053756865,"lat":411444076}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053721237,"lat":411433777}}},{"delta":{"node-LatLon":{"lon":-1053703432,"lat":411428613}}},{"delta":{"node-LatLon":{"lon":-1053685615,"lat":411423471}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053649988,"lat":411413175}}},{"delta":{"node-LatLon":{"lon":-1053632183,"lat":411408010}}},{"delta":{"node-LatLon":{"lon":-1053614378,"lat":411402847}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053578772,"lat":411392366}}},{"delta":{"node-LatLon":{"lon":-1053561555,"lat":411386056}}},{"delta":{"node-LatLon":{"lon":-1053545194,"lat":411378553}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053515122,"lat":411360665}}},{"delta":{"node-LatLon":{"lon":-1053500460,"lat":411351359}}},{"delta":{"node-LatLon":{"lon":-1053485794,"lat":411342057}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053456470,"lat":411323446}}},{"delta":{"node-LatLon":{"lon":-1053441803,"lat":411314147}}},{"delta":{"node-LatLon":{"lon":-1053427082,"lat":411304799}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053397283,"lat":411286440}}},{"delta":{"node-LatLon":{"lon":-1053381215,"lat":411278476}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411544031,"long":-1053986991}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":21}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023389,"speed":22.8,"longitude":-105.0481553},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":22,"serialNumber":15451,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31584,"packetID":"0000000000000D2C74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412034419,"long":-1054370810},"name":"eastbound_I80_325.82_329.88_SAT-99766A8D_VSL_V002155","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054327183,"lat":411987515}}},{"delta":{"node-LatLon":{"lon":-1054316162,"lat":411975689}}},{"delta":{"node-LatLon":{"lon":-1054305136,"lat":411963865}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054283086,"lat":411940217}}},{"delta":{"node-LatLon":{"lon":-1054272088,"lat":411928378}}},{"delta":{"node-LatLon":{"lon":-1054261070,"lat":411916551}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054240737,"lat":411892089}}},{"delta":{"node-LatLon":{"lon":-1054233306,"lat":411878767}}},{"delta":{"node-LatLon":{"lon":-1054228088,"lat":411864884}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054221515,"lat":411836434}}},{"delta":{"node-LatLon":{"lon":-1054217864,"lat":411822261}}},{"delta":{"node-LatLon":{"lon":-1054212576,"lat":411808389}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054197171,"lat":411782001}}},{"delta":{"node-LatLon":{"lon":-1054188029,"lat":411769320}}},{"delta":{"node-LatLon":{"lon":-1054178851,"lat":411756655}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054160547,"lat":411731223}}},{"delta":{"node-LatLon":{"lon":-1054151325,"lat":411718495}}},{"delta":{"node-LatLon":{"lon":-1054142157,"lat":411705746}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054123777,"lat":411680265}}},{"delta":{"node-LatLon":{"lon":-1054114539,"lat":411667545}}},{"delta":{"node-LatLon":{"lon":-1054105341,"lat":411654808}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054086588,"lat":411629487}}},{"delta":{"node-LatLon":{"lon":-1054076298,"lat":411617239}}},{"delta":{"node-LatLon":{"lon":-1054065465,"lat":411605534}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054041764,"lat":411583290}}},{"delta":{"node-LatLon":{"lon":-1054029028,"lat":411572740}}},{"delta":{"node-LatLon":{"lon":-1054015535,"lat":411562740}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053986991,"lat":411544031}}},{"delta":{"node-LatLon":{"lon":-1053971893,"lat":411535445}}},{"delta":{"node-LatLon":{"lon":-1053956403,"lat":411527267}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000011100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412034419,"long":-1054370810}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31584}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023389,"speed":22.8,"longitude":-105.0481553},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":21,"serialNumber":15450,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.952Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"0000000000000F6CF3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412309017,"long":-1054379125},"name":"eastbound_I80_323.85_325.82_SAT-0405F53D_VSL_V002136","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054387340,"lat":412253070}}},{"delta":{"node-LatLon":{"lon":-1054384188,"lat":412238776}}},{"delta":{"node-LatLon":{"lon":-1054383083,"lat":412224323}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054389797,"lat":412195863}}},{"delta":{"node-LatLon":{"lon":-1054394498,"lat":412181812}}},{"delta":{"node-LatLon":{"lon":-1054399238,"lat":412167769}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054408711,"lat":412139682}}},{"delta":{"node-LatLon":{"lon":-1054413260,"lat":412125813}}},{"delta":{"node-LatLon":{"lon":-1054415782,"lat":412111677}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054408252,"lat":412083905}}},{"delta":{"node-LatLon":{"lon":-1054400204,"lat":412070975}}},{"delta":{"node-LatLon":{"lon":-1054391746,"lat":412058198}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054370810,"lat":412034419}}},{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001110000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412309017,"long":-1054379125}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023349,"speed":22.72,"longitude":-105.0481818},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":20,"serialNumber":15449,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24569,"packetID":"000000000000031CC6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-60A2FC8C_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":24569}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.05,"latitude":41.102331,"speed":22.66,"longitude":-105.0482085},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":19,"serialNumber":15448,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24569,"packetID":"000000000000066E2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-8CF74104_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":24569}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.05,"latitude":41.102331,"speed":22.66,"longitude":-105.0482085},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":18,"serialNumber":15447,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24213,"packetID":"00000000000003F64F","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-70957D0D_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":24213}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.102327,"speed":22.54,"longitude":-105.0482348},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":17,"serialNumber":15446,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":23113,"packetID":"000000000000064D7E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412669811,"long":-1109265496},"name":"eastbound_I80_6.94_8.45_SAT-C9A7ABD9_VSL_V004766","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1109245942,"lat":412667616}}},{"delta":{"node-LatLon":{"lon":-1109227078,"lat":412665173}}},{"delta":{"node-LatLon":{"lon":-1109208218,"lat":412662718}}},{"delta":{"node-LatLon":{"lon":-1109189533,"lat":412659588}}},{"delta":{"node-LatLon":{"lon":-1109170944,"lat":412656149}}},{"delta":{"node-LatLon":{"lon":-1109152362,"lat":412652687}}},{"delta":{"node-LatLon":{"lon":-1109133790,"lat":412649197}}},{"delta":{"node-LatLon":{"lon":-1109115215,"lat":412645713}}},{"delta":{"node-LatLon":{"lon":-1109096639,"lat":412642235}}},{"delta":{"node-LatLon":{"lon":-1109078070,"lat":412638736}}},{"delta":{"node-LatLon":{"lon":-1109059500,"lat":412635242}}},{"delta":{"node-LatLon":{"lon":-1109040676,"lat":412631705}}},{"delta":{"node-LatLon":{"lon":-1109021836,"lat":412628219}}},{"delta":{"node-LatLon":{"lon":-1109002866,"lat":412625167}}},{"delta":{"node-LatLon":{"lon":-1108983731,"lat":412622770}}},{"delta":{"node-LatLon":{"lon":-1108964506,"lat":412620829}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412669811,"long":-1109265496}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":23113}},"msgCnt":7}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.102327,"speed":22.54,"longitude":-105.0482348},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":16,"serialNumber":15445,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002224,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411709740,"long":-1048394120},"name":"wydot_sirius_4_2_SAT-7EFD0225","laneWidth":20000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048393730,"lat":411712450}}},{"delta":{"node-LatLon":{"lon":-1048383840,"lat":411767010}}},{"delta":{"node-LatLon":{"lon":-1048380500,"lat":411794860}}},{"delta":{"node-LatLon":{"lon":-1048379990,"lat":411809560}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":2574}},{"item":{"itis":12712}},{"item":{"itis":8709}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.1375,"latitude":41.1023232,"speed":22.5,"longitude":-105.0482612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":15,"serialNumber":15444,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002223,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411606840,"long":-1048289900},"name":"wydot_sirius_3_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048291070,"lat":411607850}}},{"delta":{"node-LatLon":{"lon":-1048323850,"lat":411632860}}},{"delta":{"node-LatLon":{"lon":-1048323850,"lat":411632860}}},{"delta":{"node-LatLon":{"lon":-1048338000,"lat":411643250}}},{"delta":{"node-LatLon":{"lon":-1048357350,"lat":411654510}}},{"delta":{"node-LatLon":{"lon":-1048383680,"lat":411667660}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4868}},{"item":{"itis":5907}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.1375,"latitude":41.1023232,"speed":22.5,"longitude":-105.0482612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":14,"serialNumber":15443,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002222,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411713780,"long":-1048286250},"name":"wydot_sirius_2_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048286250,"lat":411712160}}},{"delta":{"node-LatLon":{"lon":-1048287580,"lat":411641030}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001111000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12579}},{"item":{"itis":8720}},{"item":{"itis":1025}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023195,"speed":22.4,"longitude":-105.0482875},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":13,"serialNumber":15442,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002221,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411751930,"long":-1048286330},"name":"wydot_sirius_1_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048286640,"lat":411748120}}},{"delta":{"node-LatLon":{"lon":-1048286110,"lat":411713600}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001111000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":7443}},{"item":{"itis":12579}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023157,"speed":22.22,"longitude":-105.0483139},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":12,"serialNumber":15441,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31504,"packetID":"0000000000000C6FA0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415389123,"long":-1060795306},"name":"eastbound_I80_280.36_291.0_SAT-9970CD4E_VSL_V000417","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060783562,"lat":415377559}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}},{"delta":{"node-LatLon":{"lon":-1060748924,"lat":415342529}}},{"delta":{"node-LatLon":{"lon":-1060725901,"lat":415319138}}},{"delta":{"node-LatLon":{"lon":-1060702891,"lat":415295740}}},{"delta":{"node-LatLon":{"lon":-1060677392,"lat":415274709}}},{"delta":{"node-LatLon":{"lon":-1060645465,"lat":415259440}}},{"delta":{"node-LatLon":{"lon":-1060611694,"lat":415246452}}},{"delta":{"node-LatLon":{"lon":-1060583936,"lat":415227230}}},{"delta":{"node-LatLon":{"lon":-1060567112,"lat":415201829}}},{"delta":{"node-LatLon":{"lon":-1060559250,"lat":415173268}}},{"delta":{"node-LatLon":{"lon":-1060551848,"lat":415144627}}},{"delta":{"node-LatLon":{"lon":-1060544578,"lat":415115967}}},{"delta":{"node-LatLon":{"lon":-1060537212,"lat":415087321}}},{"delta":{"node-LatLon":{"lon":-1060528192,"lat":415058965}}},{"delta":{"node-LatLon":{"lon":-1060513843,"lat":415031898}}},{"delta":{"node-LatLon":{"lon":-1060498684,"lat":415005075}}},{"delta":{"node-LatLon":{"lon":-1060479584,"lat":414979768}}},{"delta":{"node-LatLon":{"lon":-1060454612,"lat":414957536}}},{"delta":{"node-LatLon":{"lon":-1060424994,"lat":414938765}}},{"delta":{"node-LatLon":{"lon":-1060394265,"lat":414920704}}},{"delta":{"node-LatLon":{"lon":-1060362947,"lat":414903230}}},{"delta":{"node-LatLon":{"lon":-1060331139,"lat":414886261}}},{"delta":{"node-LatLon":{"lon":-1060299282,"lat":414869343}}},{"delta":{"node-LatLon":{"lon":-1060267401,"lat":414852453}}},{"delta":{"node-LatLon":{"lon":-1060236377,"lat":414836034}}},{"delta":{"node-LatLon":{"lon":-1060205413,"lat":414819550}}},{"delta":{"node-LatLon":{"lon":-1060174405,"lat":414803116}}},{"delta":{"node-LatLon":{"lon":-1060143426,"lat":414786651}}},{"delta":{"node-LatLon":{"lon":-1060112442,"lat":414770191}}},{"delta":{"node-LatLon":{"lon":-1060080853,"lat":414753421}}},{"delta":{"node-LatLon":{"lon":-1060049273,"lat":414736640}}},{"delta":{"node-LatLon":{"lon":-1060017699,"lat":414719856}}},{"delta":{"node-LatLon":{"lon":-1059986118,"lat":414703079}}},{"delta":{"node-LatLon":{"lon":-1059954550,"lat":414686289}}},{"delta":{"node-LatLon":{"lon":-1059923262,"lat":414669701}}},{"delta":{"node-LatLon":{"lon":-1059892003,"lat":414653083}}},{"delta":{"node-LatLon":{"lon":-1059860748,"lat":414636462}}},{"delta":{"node-LatLon":{"lon":-1059830894,"lat":414618511}}},{"delta":{"node-LatLon":{"lon":-1059806580,"lat":414596316}}},{"delta":{"node-LatLon":{"lon":-1059783729,"lat":414573041}}},{"delta":{"node-LatLon":{"lon":-1059760839,"lat":414549787}}},{"delta":{"node-LatLon":{"lon":-1059737946,"lat":414526535}}},{"delta":{"node-LatLon":{"lon":-1059715065,"lat":414503278}}},{"delta":{"node-LatLon":{"lon":-1059692206,"lat":414480008}}},{"delta":{"node-LatLon":{"lon":-1059665100,"lat":414457204}}},{"delta":{"node-LatLon":{"lon":-1059630733,"lat":414440918}}},{"delta":{"node-LatLon":{"lon":-1059592047,"lat":414431361}}},{"delta":{"node-LatLon":{"lon":-1059552953,"lat":414422717}}},{"delta":{"node-LatLon":{"lon":-1059513468,"lat":414415217}}},{"delta":{"node-LatLon":{"lon":-1059476558,"lat":414409805}}},{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059402750,"lat":414398944}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059328946,"lat":414388067}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415389123,"long":-1060795306}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31504}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023157,"speed":22.22,"longitude":-105.0483139},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":11,"serialNumber":15440,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"000000000000028D2E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415887613,"long":-1061814678},"name":"eastbound_I80_273.85_280.36_SAT-307505E1_VSL_V000424","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060818850,"lat":415412221}}},{"delta":{"node-LatLon":{"lon":-1060795306,"lat":415389123}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415887613,"long":-1061814678}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023118,"speed":22.22,"longitude":-105.0483399},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":10,"serialNumber":15439,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000C462C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416299496,"long":-1062778698},"name":"eastbound_I80_267.71_273.85_SAT-54C5D564_VSL_V000428","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061783879,"lat":415869849}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416299496,"long":-1062778698}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":34}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023118,"speed":22.22,"longitude":-105.0483399},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":9,"serialNumber":15438,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000EDB21","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416667387,"long":-1063664504},"name":"eastbound_I80_262.4_267.71_SAT-2AAB775E_VSL_V000433","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1063648291,"lat":416659518}}},{"delta":{"node-LatLon":{"lon":-1063632072,"lat":416651657}}},{"delta":{"node-LatLon":{"lon":-1063615844,"lat":416643807}}},{"delta":{"node-LatLon":{"lon":-1063599618,"lat":416635954}}},{"delta":{"node-LatLon":{"lon":-1063583366,"lat":416628132}}},{"delta":{"node-LatLon":{"lon":-1063567147,"lat":416620270}}},{"delta":{"node-LatLon":{"lon":-1063550917,"lat":416612423}}},{"delta":{"node-LatLon":{"lon":-1063534665,"lat":416604565}}},{"delta":{"node-LatLon":{"lon":-1063518397,"lat":416596725}}},{"delta":{"node-LatLon":{"lon":-1063502152,"lat":416588858}}},{"delta":{"node-LatLon":{"lon":-1063485899,"lat":416581001}}},{"delta":{"node-LatLon":{"lon":-1063469644,"lat":416573146}}},{"delta":{"node-LatLon":{"lon":-1063453403,"lat":416565276}}},{"delta":{"node-LatLon":{"lon":-1063437145,"lat":416557426}}},{"delta":{"node-LatLon":{"lon":-1063420938,"lat":416549517}}},{"delta":{"node-LatLon":{"lon":-1063404651,"lat":416541700}}},{"delta":{"node-LatLon":{"lon":-1063388402,"lat":416533840}}},{"delta":{"node-LatLon":{"lon":-1063372187,"lat":416525964}}},{"delta":{"node-LatLon":{"lon":-1063355954,"lat":416518111}}},{"delta":{"node-LatLon":{"lon":-1063339726,"lat":416510251}}},{"delta":{"node-LatLon":{"lon":-1063323497,"lat":416502393}}},{"delta":{"node-LatLon":{"lon":-1063307259,"lat":416494545}}},{"delta":{"node-LatLon":{"lon":-1063291009,"lat":416486712}}},{"delta":{"node-LatLon":{"lon":-1063274801,"lat":416478829}}},{"delta":{"node-LatLon":{"lon":-1063258568,"lat":416470977}}},{"delta":{"node-LatLon":{"lon":-1063242340,"lat":416463119}}},{"delta":{"node-LatLon":{"lon":-1063226121,"lat":416455250}}},{"delta":{"node-LatLon":{"lon":-1063209373,"lat":416447767}}},{"delta":{"node-LatLon":{"lon":-1063191824,"lat":416441408}}},{"delta":{"node-LatLon":{"lon":-1063173583,"lat":416436257}}},{"delta":{"node-LatLon":{"lon":-1063154787,"lat":416432390}}},{"delta":{"node-LatLon":{"lon":-1063135782,"lat":416429129}}},{"delta":{"node-LatLon":{"lon":-1063116772,"lat":416425883}}},{"delta":{"node-LatLon":{"lon":-1063097755,"lat":416422664}}},{"delta":{"node-LatLon":{"lon":-1063078751,"lat":416419398}}},{"delta":{"node-LatLon":{"lon":-1063059740,"lat":416416159}}},{"delta":{"node-LatLon":{"lon":-1063040728,"lat":416412924}}},{"delta":{"node-LatLon":{"lon":-1063021827,"lat":416409723}}},{"delta":{"node-LatLon":{"lon":-1063002941,"lat":416406471}}},{"delta":{"node-LatLon":{"lon":-1062984045,"lat":416403256}}},{"delta":{"node-LatLon":{"lon":-1062965166,"lat":416399984}}},{"delta":{"node-LatLon":{"lon":-1062946625,"lat":416395793}}},{"delta":{"node-LatLon":{"lon":-1062928900,"lat":416389943}}},{"delta":{"node-LatLon":{"lon":-1062912200,"lat":416382587}}},{"delta":{"node-LatLon":{"lon":-1062896756,"lat":416373819}}},{"delta":{"node-LatLon":{"lon":-1062881956,"lat":416364437}}},{"delta":{"node-LatLon":{"lon":-1062867209,"lat":416355008}}},{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416667387,"long":-1063664504}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":31}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":7,"serialNumber":15436,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000C0339","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416385526,"long":-1062907286},"name":"westbound_I80_266.58_259.77_SAT-2470209F_VSL_V000430","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062961089,"lat":416403834}}},{"delta":{"node-LatLon":{"lon":-1062999651,"lat":416410539}}},{"delta":{"node-LatLon":{"lon":-1063038256,"lat":416417110}}},{"delta":{"node-LatLon":{"lon":-1063075838,"lat":416423525}}},{"delta":{"node-LatLon":{"lon":-1063113422,"lat":416429935}}},{"delta":{"node-LatLon":{"lon":-1063151010,"lat":416436333}}},{"delta":{"node-LatLon":{"lon":-1063187758,"lat":416444929}}},{"delta":{"node-LatLon":{"lon":-1063221748,"lat":416458478}}},{"delta":{"node-LatLon":{"lon":-1063254248,"lat":416474223}}},{"delta":{"node-LatLon":{"lon":-1063286767,"lat":416489947}}},{"delta":{"node-LatLon":{"lon":-1063319286,"lat":416505671}}},{"delta":{"node-LatLon":{"lon":-1063351803,"lat":416521398}}},{"delta":{"node-LatLon":{"lon":-1063384308,"lat":416537141}}},{"delta":{"node-LatLon":{"lon":-1063416537,"lat":416552741}}},{"delta":{"node-LatLon":{"lon":-1063448756,"lat":416568353}}},{"delta":{"node-LatLon":{"lon":-1063480997,"lat":416583940}}},{"delta":{"node-LatLon":{"lon":-1063513230,"lat":416599539}}},{"delta":{"node-LatLon":{"lon":-1063545479,"lat":416615118}}},{"delta":{"node-LatLon":{"lon":-1063577703,"lat":416630746}}},{"delta":{"node-LatLon":{"lon":-1063609979,"lat":416646315}}},{"delta":{"node-LatLon":{"lon":-1063642246,"lat":416661894}}},{"delta":{"node-LatLon":{"lon":-1063674320,"lat":416677693}}},{"delta":{"node-LatLon":{"lon":-1063702475,"lat":416697159}}},{"delta":{"node-LatLon":{"lon":-1063724503,"lat":416721905}}},{"delta":{"node-LatLon":{"lon":-1063738013,"lat":416749885}}},{"delta":{"node-LatLon":{"lon":-1063745688,"lat":416779149}}},{"delta":{"node-LatLon":{"lon":-1063757512,"lat":416807580}}},{"delta":{"node-LatLon":{"lon":-1063775542,"lat":416834147}}},{"delta":{"node-LatLon":{"lon":-1063793398,"lat":416858977}}},{"delta":{"node-LatLon":{"lon":-1063809837,"lat":416884350}}},{"delta":{"node-LatLon":{"lon":-1063824918,"lat":416910195}}},{"delta":{"node-LatLon":{"lon":-1063839847,"lat":416936091}}},{"delta":{"node-LatLon":{"lon":-1063856289,"lat":416961436}}},{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063894506,"lat":416994252}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416385526,"long":-1062907286}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":8,"serialNumber":15437,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000FE5E4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416973452,"long":-1063867317},"name":"westbound_I80_259.77_254.87_SAT-6C9DA4E2_VSL_V000435","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063894506,"lat":416994252}}},{"delta":{"node-LatLon":{"lon":-1063910309,"lat":417002755}}},{"delta":{"node-LatLon":{"lon":-1063927293,"lat":417009870}}},{"delta":{"node-LatLon":{"lon":-1063944810,"lat":417016237}}},{"delta":{"node-LatLon":{"lon":-1063962371,"lat":417022536}}},{"delta":{"node-LatLon":{"lon":-1063979929,"lat":417028841}}},{"delta":{"node-LatLon":{"lon":-1063997487,"lat":417035145}}},{"delta":{"node-LatLon":{"lon":-1064015050,"lat":417041442}}},{"delta":{"node-LatLon":{"lon":-1064032545,"lat":417047634}}},{"delta":{"node-LatLon":{"lon":-1064050617,"lat":417052787}}},{"delta":{"node-LatLon":{"lon":-1064069340,"lat":417056404}}},{"delta":{"node-LatLon":{"lon":-1064088491,"lat":417058422}}},{"delta":{"node-LatLon":{"lon":-1064107803,"lat":417059292}}},{"delta":{"node-LatLon":{"lon":-1064127128,"lat":417059995}}},{"delta":{"node-LatLon":{"lon":-1064146451,"lat":417060728}}},{"delta":{"node-LatLon":{"lon":-1064165769,"lat":417061539}}},{"delta":{"node-LatLon":{"lon":-1064185091,"lat":417062288}}},{"delta":{"node-LatLon":{"lon":-1064204408,"lat":417063119}}},{"delta":{"node-LatLon":{"lon":-1064223632,"lat":417064590}}},{"delta":{"node-LatLon":{"lon":-1064242489,"lat":417067748}}},{"delta":{"node-LatLon":{"lon":-1064260716,"lat":417072554}}},{"delta":{"node-LatLon":{"lon":-1064278067,"lat":417078928}}},{"delta":{"node-LatLon":{"lon":-1064294308,"lat":417086774}}},{"delta":{"node-LatLon":{"lon":-1064309216,"lat":417095993}}},{"delta":{"node-LatLon":{"lon":-1064323678,"lat":417105610}}},{"delta":{"node-LatLon":{"lon":-1064338068,"lat":417115288}}},{"delta":{"node-LatLon":{"lon":-1064352499,"lat":417124933}}},{"delta":{"node-LatLon":{"lon":-1064366996,"lat":417134521}}},{"delta":{"node-LatLon":{"lon":-1064381609,"lat":417143889}}},{"delta":{"node-LatLon":{"lon":-1064396523,"lat":417152988}}},{"delta":{"node-LatLon":{"lon":-1064411727,"lat":417161812}}},{"delta":{"node-LatLon":{"lon":-1064427177,"lat":417170394}}},{"delta":{"node-LatLon":{"lon":-1064442869,"lat":417178725}}},{"delta":{"node-LatLon":{"lon":-1064458838,"lat":417186756}}},{"delta":{"node-LatLon":{"lon":-1064475045,"lat":417194514}}},{"delta":{"node-LatLon":{"lon":-1064491487,"lat":417201990}}},{"delta":{"node-LatLon":{"lon":-1064508131,"lat":417209211}}},{"delta":{"node-LatLon":{"lon":-1064525046,"lat":417216068}}},{"delta":{"node-LatLon":{"lon":-1064542331,"lat":417222795}}},{"delta":{"node-LatLon":{"lon":-1064559666,"lat":417229448}}},{"delta":{"node-LatLon":{"lon":-1064577050,"lat":417236030}}},{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}},{"delta":{"node-LatLon":{"lon":-1064611800,"lat":417249219}}},{"delta":{"node-LatLon":{"lon":-1064629183,"lat":417255803}}},{"delta":{"node-LatLon":{"lon":-1064646550,"lat":417262411}}},{"delta":{"node-LatLon":{"lon":-1064663938,"lat":417268988}}},{"delta":{"node-LatLon":{"lon":-1064681335,"lat":417275551}}},{"delta":{"node-LatLon":{"lon":-1064698689,"lat":417282178}}},{"delta":{"node-LatLon":{"lon":-1064715850,"lat":417288659}}},{"delta":{"node-LatLon":{"lon":-1064732992,"lat":417295169}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001100"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416973452,"long":-1063867317}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":6,"serialNumber":15435,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.053Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"00000000000004B2BA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415980789,"long":-1062129021},"name":"westbound_I80_271.8_266.58_SAT-129A26E5_VSL_V000426","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}},{"delta":{"node-LatLon":{"lon":-1062861444,"lat":416357241}}},{"delta":{"node-LatLon":{"lon":-1062876541,"lat":416366844}}},{"delta":{"node-LatLon":{"lon":-1062891617,"lat":416376465}}},{"delta":{"node-LatLon":{"lon":-1062907286,"lat":416385526}}},{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062942253,"lat":416399303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415980789,"long":-1062129021}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":24}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9875,"latitude":41.1023005,"speed":22.12,"longitude":-105.0484177},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":5,"serialNumber":15434,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.053Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"0000000000000D81DE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415470937,"long":-1060871344},"name":"westbound_I80_279.36_271.8_SAT-06EB7A5B_VSL_V000422","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415470937,"long":-1060871344}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9875,"latitude":41.1023005,"speed":22.12,"longitude":-105.0484177},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":4,"serialNumber":15433,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.963Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31504,"packetID":"0000000000000B0C4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414434951,"long":-1059587159},"name":"westbound_I80_289.5_279.36_SAT-FDFB3C3B_VSL_V000416","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059606146,"lat":414439136}}},{"delta":{"node-LatLon":{"lon":-1059624866,"lat":414443931}}},{"delta":{"node-LatLon":{"lon":-1059658797,"lat":414459046}}},{"delta":{"node-LatLon":{"lon":-1059685629,"lat":414480816}}},{"delta":{"node-LatLon":{"lon":-1059708612,"lat":414504233}}},{"delta":{"node-LatLon":{"lon":-1059731631,"lat":414527631}}},{"delta":{"node-LatLon":{"lon":-1059754662,"lat":414551022}}},{"delta":{"node-LatLon":{"lon":-1059777663,"lat":414574431}}},{"delta":{"node-LatLon":{"lon":-1059800605,"lat":414597873}}},{"delta":{"node-LatLon":{"lon":-1059825019,"lat":414620504}}},{"delta":{"node-LatLon":{"lon":-1059854975,"lat":414638959}}},{"delta":{"node-LatLon":{"lon":-1059886652,"lat":414655790}}},{"delta":{"node-LatLon":{"lon":-1059918347,"lat":414672602}}},{"delta":{"node-LatLon":{"lon":-1059950027,"lat":414689430}}},{"delta":{"node-LatLon":{"lon":-1059981533,"lat":414706207}}},{"delta":{"node-LatLon":{"lon":-1060013094,"lat":414722925}}},{"delta":{"node-LatLon":{"lon":-1060044644,"lat":414739656}}},{"delta":{"node-LatLon":{"lon":-1060076151,"lat":414756434}}},{"delta":{"node-LatLon":{"lon":-1060107672,"lat":414773199}}},{"delta":{"node-LatLon":{"lon":-1060138668,"lat":414789614}}},{"delta":{"node-LatLon":{"lon":-1060169596,"lat":414806103}}},{"delta":{"node-LatLon":{"lon":-1060200600,"lat":414822512}}},{"delta":{"node-LatLon":{"lon":-1060231565,"lat":414838964}}},{"delta":{"node-LatLon":{"lon":-1060262552,"lat":414855394}}},{"delta":{"node-LatLon":{"lon":-1060294303,"lat":414872314}}},{"delta":{"node-LatLon":{"lon":-1060326101,"lat":414889184}}},{"delta":{"node-LatLon":{"lon":-1060357880,"lat":414906076}}},{"delta":{"node-LatLon":{"lon":-1060389415,"lat":414923223}}},{"delta":{"node-LatLon":{"lon":-1060420573,"lat":414940760}}},{"delta":{"node-LatLon":{"lon":-1060450509,"lat":414958838}}},{"delta":{"node-LatLon":{"lon":-1060475868,"lat":414980491}}},{"delta":{"node-LatLon":{"lon":-1060495507,"lat":415005280}}},{"delta":{"node-LatLon":{"lon":-1060510699,"lat":415031818}}},{"delta":{"node-LatLon":{"lon":-1060524843,"lat":415058673}}},{"delta":{"node-LatLon":{"lon":-1060533417,"lat":415086879}}},{"delta":{"node-LatLon":{"lon":-1060540264,"lat":415115378}}},{"delta":{"node-LatLon":{"lon":-1060547197,"lat":415143865}}},{"delta":{"node-LatLon":{"lon":-1060554077,"lat":415172359}}},{"delta":{"node-LatLon":{"lon":-1060561492,"lat":415200772}}},{"delta":{"node-LatLon":{"lon":-1060576552,"lat":415227429}}},{"delta":{"node-LatLon":{"lon":-1060600749,"lat":415249961}}},{"delta":{"node-LatLon":{"lon":-1060632200,"lat":415266697}}},{"delta":{"node-LatLon":{"lon":-1060666183,"lat":415280527}}},{"delta":{"node-LatLon":{"lon":-1060695463,"lat":415299353}}},{"delta":{"node-LatLon":{"lon":-1060719162,"lat":415322019}}},{"delta":{"node-LatLon":{"lon":-1060742498,"lat":415344904}}},{"delta":{"node-LatLon":{"lon":-1060765869,"lat":415367768}}},{"delta":{"node-LatLon":{"lon":-1060789259,"lat":415390622}}},{"delta":{"node-LatLon":{"lon":-1060812632,"lat":415413487}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060894883,"lat":415493886}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414434951,"long":-1059587159}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31504}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":3,"serialNumber":15432,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.963Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31267,"packetID":"000000000000094275","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417772272,"long":-1073083802},"name":"westbound_I80_187.2_209.5_SAT-B0DDD576_RC_RAWI80WRSD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1073103032,"lat":417770765}}},{"delta":{"node-LatLon":{"lon":-1073160734,"lat":417766344}}},{"delta":{"node-LatLon":{"lon":-1073237348,"lat":417761297}}},{"delta":{"node-LatLon":{"lon":-1073313648,"lat":417764434}}},{"delta":{"node-LatLon":{"lon":-1073388010,"lat":417777604}}},{"delta":{"node-LatLon":{"lon":-1073460227,"lat":417797785}}},{"delta":{"node-LatLon":{"lon":-1073532308,"lat":417818249}}},{"delta":{"node-LatLon":{"lon":-1073604685,"lat":417838835}}},{"delta":{"node-LatLon":{"lon":-1073677383,"lat":417859492}}},{"delta":{"node-LatLon":{"lon":-1073750200,"lat":417879909}}},{"delta":{"node-LatLon":{"lon":-1073825885,"lat":417892315}}},{"delta":{"node-LatLon":{"lon":-1073903361,"lat":417891911}}},{"delta":{"node-LatLon":{"lon":-1073980790,"lat":417878755}}},{"delta":{"node-LatLon":{"lon":-1074059270,"lat":417862672}}},{"delta":{"node-LatLon":{"lon":-1074138797,"lat":417849816}}},{"delta":{"node-LatLon":{"lon":-1074212379,"lat":417833423}}},{"delta":{"node-LatLon":{"lon":-1074285917,"lat":417816922}}},{"delta":{"node-LatLon":{"lon":-1074359753,"lat":417800402}}},{"delta":{"node-LatLon":{"lon":-1074433865,"lat":417783809}}},{"delta":{"node-LatLon":{"lon":-1074507971,"lat":417767209}}},{"delta":{"node-LatLon":{"lon":-1074582466,"lat":417750471}}},{"delta":{"node-LatLon":{"lon":-1074656974,"lat":417733772}}},{"delta":{"node-LatLon":{"lon":-1074730980,"lat":417717212}}},{"delta":{"node-LatLon":{"lon":-1074804466,"lat":417700741}}},{"delta":{"node-LatLon":{"lon":-1074877974,"lat":417684333}}},{"delta":{"node-LatLon":{"lon":-1074952181,"lat":417667699}}},{"delta":{"node-LatLon":{"lon":-1075026384,"lat":417651055}}},{"delta":{"node-LatLon":{"lon":-1075100631,"lat":417634583}}},{"delta":{"node-LatLon":{"lon":-1075174927,"lat":417618293}}},{"delta":{"node-LatLon":{"lon":-1075249229,"lat":417602021}}},{"delta":{"node-LatLon":{"lon":-1075324198,"lat":417585522}}},{"delta":{"node-LatLon":{"lon":-1075399202,"lat":417569122}}},{"delta":{"node-LatLon":{"lon":-1075474679,"lat":417552532}}},{"delta":{"node-LatLon":{"lon":-1075550650,"lat":417535815}}},{"delta":{"node-LatLon":{"lon":-1075626641,"lat":417519150}}},{"delta":{"node-LatLon":{"lon":-1075700169,"lat":417503005}}},{"delta":{"node-LatLon":{"lon":-1075773956,"lat":417487570}}},{"delta":{"node-LatLon":{"lon":-1075849915,"lat":417477896}}},{"delta":{"node-LatLon":{"lon":-1075927140,"lat":417472412}}},{"delta":{"node-LatLon":{"lon":-1076004368,"lat":417466944}}},{"delta":{"node-LatLon":{"lon":-1076078363,"lat":417461740}}},{"delta":{"node-LatLon":{"lon":-1076152354,"lat":417456501}}},{"delta":{"node-LatLon":{"lon":-1076228617,"lat":417451146}}},{"delta":{"node-LatLon":{"lon":-1076306386,"lat":417445637}}},{"delta":{"node-LatLon":{"lon":-1076384155,"lat":417440136}}},{"delta":{"node-LatLon":{"lon":-1076461786,"lat":417434636}}},{"delta":{"node-LatLon":{"lon":-1076539413,"lat":417429098}}},{"delta":{"node-LatLon":{"lon":-1076616980,"lat":417423684}}},{"delta":{"node-LatLon":{"lon":-1076694352,"lat":417417431}}},{"delta":{"node-LatLon":{"lon":-1076769822,"lat":417403428}}},{"delta":{"node-LatLon":{"lon":-1076844263,"lat":417386508}}},{"delta":{"node-LatLon":{"lon":-1076918694,"lat":417369570}}},{"delta":{"node-LatLon":{"lon":-1076992959,"lat":417352731}}},{"delta":{"node-LatLon":{"lon":-1077067009,"lat":417335868}}},{"delta":{"node-LatLon":{"lon":-1077141060,"lat":417319013}}},{"delta":{"node-LatLon":{"lon":-1077216222,"lat":417301908}}},{"delta":{"node-LatLon":{"lon":-1077291383,"lat":417284807}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417772272,"long":-1073083802}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31267}},"msgCnt":90}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":2,"serialNumber":15431,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31267,"packetID":"000000000000024E94","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417275428,"long":-1077311709},"name":"eastbound_I80_187.2_209.5_SAT-0A794CC9_RC_RAWI80WRSI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1077292868,"lat":417279720}}},{"delta":{"node-LatLon":{"lon":-1077217513,"lat":417296919}}},{"delta":{"node-LatLon":{"lon":-1077142143,"lat":417314087}}},{"delta":{"node-LatLon":{"lon":-1077068049,"lat":417330933}}},{"delta":{"node-LatLon":{"lon":-1076993961,"lat":417347795}}},{"delta":{"node-LatLon":{"lon":-1076919664,"lat":417364670}}},{"delta":{"node-LatLon":{"lon":-1076845181,"lat":417381611}}},{"delta":{"node-LatLon":{"lon":-1076770688,"lat":417398531}}},{"delta":{"node-LatLon":{"lon":-1076695769,"lat":417412771}}},{"delta":{"node-LatLon":{"lon":-1076618859,"lat":417418968}}},{"delta":{"node-LatLon":{"lon":-1076541598,"lat":417424427}}},{"delta":{"node-LatLon":{"lon":-1076464105,"lat":417429921}}},{"delta":{"node-LatLon":{"lon":-1076386610,"lat":417435404}}},{"delta":{"node-LatLon":{"lon":-1076309252,"lat":417440926}}},{"delta":{"node-LatLon":{"lon":-1076231889,"lat":417446401}}},{"delta":{"node-LatLon":{"lon":-1076155879,"lat":417451762}}},{"delta":{"node-LatLon":{"lon":-1076081223,"lat":417457006}}},{"delta":{"node-LatLon":{"lon":-1076006571,"lat":417462290}}},{"delta":{"node-LatLon":{"lon":-1075928925,"lat":417467718}}},{"delta":{"node-LatLon":{"lon":-1075851297,"lat":417473296}}},{"delta":{"node-LatLon":{"lon":-1075775135,"lat":417482757}}},{"delta":{"node-LatLon":{"lon":-1075701404,"lat":417498056}}},{"delta":{"node-LatLon":{"lon":-1075627970,"lat":417514175}}},{"delta":{"node-LatLon":{"lon":-1075551546,"lat":417530959}}},{"delta":{"node-LatLon":{"lon":-1075475121,"lat":417547742}}},{"delta":{"node-LatLon":{"lon":-1075399612,"lat":417564374}}},{"delta":{"node-LatLon":{"lon":-1075324973,"lat":417580735}}},{"delta":{"node-LatLon":{"lon":-1075250327,"lat":417597082}}},{"delta":{"node-LatLon":{"lon":-1075175762,"lat":417613457}}},{"delta":{"node-LatLon":{"lon":-1075101172,"lat":417629774}}},{"delta":{"node-LatLon":{"lon":-1075026992,"lat":417646108}}},{"delta":{"node-LatLon":{"lon":-1074953281,"lat":417662619}}},{"delta":{"node-LatLon":{"lon":-1074879569,"lat":417679134}}},{"delta":{"node-LatLon":{"lon":-1074805891,"lat":417695635}}},{"delta":{"node-LatLon":{"lon":-1074732212,"lat":417712139}}},{"delta":{"node-LatLon":{"lon":-1074658253,"lat":417728674}}},{"delta":{"node-LatLon":{"lon":-1074584060,"lat":417745361}}},{"delta":{"node-LatLon":{"lon":-1074509845,"lat":417761996}}},{"delta":{"node-LatLon":{"lon":-1074435611,"lat":417778588}}},{"delta":{"node-LatLon":{"lon":-1074361397,"lat":417795237}}},{"delta":{"node-LatLon":{"lon":-1074287484,"lat":417811796}}},{"delta":{"node-LatLon":{"lon":-1074213869,"lat":417828258}}},{"delta":{"node-LatLon":{"lon":-1074140155,"lat":417844465}}},{"delta":{"node-LatLon":{"lon":-1074062164,"lat":417855879}}},{"delta":{"node-LatLon":{"lon":-1073983504,"lat":417864579}}},{"delta":{"node-LatLon":{"lon":-1073906783,"lat":417873095}}},{"delta":{"node-LatLon":{"lon":-1073831510,"lat":417877605}}},{"delta":{"node-LatLon":{"lon":-1073756373,"lat":417872063}}},{"delta":{"node-LatLon":{"lon":-1073681801,"lat":417855903}}},{"delta":{"node-LatLon":{"lon":-1073609122,"lat":417835248}}},{"delta":{"node-LatLon":{"lon":-1073536658,"lat":417814684}}},{"delta":{"node-LatLon":{"lon":-1073464445,"lat":417794142}}},{"delta":{"node-LatLon":{"lon":-1073392087,"lat":417773900}}},{"delta":{"node-LatLon":{"lon":-1073317135,"lat":417760222}}},{"delta":{"node-LatLon":{"lon":-1073240133,"lat":417756689}}},{"delta":{"node-LatLon":{"lon":-1073163130,"lat":417761557}}},{"delta":{"node-LatLon":{"lon":-1073105417,"lat":417766002}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417275428,"long":-1077311709}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":31267}},"msgCnt":78}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":1,"serialNumber":15430,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":22692,"packetID":"00000000000006AD92","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416344087,"long":-1082586926},"name":"westbound_I80_142.17_158.55_SAT-44ADF832_RC_PDI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082605867,"lat":416341147}}},{"delta":{"node-LatLon":{"lon":-1082643762,"lat":416335317}}},{"delta":{"node-LatLon":{"lon":-1082719537,"lat":416323607}}},{"delta":{"node-LatLon":{"lon":-1082795332,"lat":416311823}}},{"delta":{"node-LatLon":{"lon":-1082871219,"lat":416300396}}},{"delta":{"node-LatLon":{"lon":-1082948412,"lat":416300333}}},{"delta":{"node-LatLon":{"lon":-1083025592,"lat":416303069}}},{"delta":{"node-LatLon":{"lon":-1083102774,"lat":416305783}}},{"delta":{"node-LatLon":{"lon":-1083179715,"lat":416308441}}},{"delta":{"node-LatLon":{"lon":-1083256650,"lat":416311187}}},{"delta":{"node-LatLon":{"lon":-1083333670,"lat":416313866}}},{"delta":{"node-LatLon":{"lon":-1083410768,"lat":416316579}}},{"delta":{"node-LatLon":{"lon":-1083487872,"lat":416319193}}},{"delta":{"node-LatLon":{"lon":-1083564905,"lat":416322423}}},{"delta":{"node-LatLon":{"lon":-1083641683,"lat":416328142}}},{"delta":{"node-LatLon":{"lon":-1083718587,"lat":416332876}}},{"delta":{"node-LatLon":{"lon":-1083795496,"lat":416337572}}},{"delta":{"node-LatLon":{"lon":-1083872405,"lat":416342269}}},{"delta":{"node-LatLon":{"lon":-1083949300,"lat":416347096}}},{"delta":{"node-LatLon":{"lon":-1084026064,"lat":416352984}}},{"delta":{"node-LatLon":{"lon":-1084103063,"lat":416357400}}},{"delta":{"node-LatLon":{"lon":-1084180198,"lat":416361177}}},{"delta":{"node-LatLon":{"lon":-1084257244,"lat":416365879}}},{"delta":{"node-LatLon":{"lon":-1084326673,"lat":416370105}}},{"delta":{"node-LatLon":{"lon":-1084396100,"lat":416374353}}},{"delta":{"node-LatLon":{"lon":-1084469893,"lat":416378867}}},{"delta":{"node-LatLon":{"lon":-1084548056,"lat":416383611}}},{"delta":{"node-LatLon":{"lon":-1084626220,"lat":416388347}}},{"delta":{"node-LatLon":{"lon":-1084703702,"lat":416393060}}},{"delta":{"node-LatLon":{"lon":-1084781188,"lat":416397734}}},{"delta":{"node-LatLon":{"lon":-1084859010,"lat":416402450}}},{"delta":{"node-LatLon":{"lon":-1084937168,"lat":416407197}}},{"delta":{"node-LatLon":{"lon":-1085015328,"lat":416411930}}},{"delta":{"node-LatLon":{"lon":-1085093024,"lat":416416612}}},{"delta":{"node-LatLon":{"lon":-1085170718,"lat":416421321}}},{"delta":{"node-LatLon":{"lon":-1085248418,"lat":416425954}}},{"delta":{"node-LatLon":{"lon":-1085326100,"lat":416430747}}},{"delta":{"node-LatLon":{"lon":-1085403806,"lat":416435322}}},{"delta":{"node-LatLon":{"lon":-1085482142,"lat":416440051}}},{"delta":{"node-LatLon":{"lon":-1085560481,"lat":416444752}}},{"delta":{"node-LatLon":{"lon":-1085638702,"lat":416449395}}},{"delta":{"node-LatLon":{"lon":-1085716794,"lat":416454065}}},{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416344087,"long":-1082586926}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":22692}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} -{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":15429,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":22692,"packetID":"000000000000086861","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416455490,"long":-1085800440},"name":"eastbound_I80_142.17_158.55_SAT-1C6D23BF_RC_PDI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085780958,"lat":416453533}}},{"delta":{"node-LatLon":{"lon":-1085722182,"lat":416449943}}},{"delta":{"node-LatLon":{"lon":-1085643804,"lat":416445230}}},{"delta":{"node-LatLon":{"lon":-1085565424,"lat":416440540}}},{"delta":{"node-LatLon":{"lon":-1085487043,"lat":416435869}}},{"delta":{"node-LatLon":{"lon":-1085408668,"lat":416431146}}},{"delta":{"node-LatLon":{"lon":-1085330293,"lat":416426421}}},{"delta":{"node-LatLon":{"lon":-1085251916,"lat":416421727}}},{"delta":{"node-LatLon":{"lon":-1085173902,"lat":416416997}}},{"delta":{"node-LatLon":{"lon":-1085096242,"lat":416412330}}},{"delta":{"node-LatLon":{"lon":-1085018585,"lat":416407636}}},{"delta":{"node-LatLon":{"lon":-1084940663,"lat":416402897}}},{"delta":{"node-LatLon":{"lon":-1084862741,"lat":416398163}}},{"delta":{"node-LatLon":{"lon":-1084784815,"lat":416393472}}},{"delta":{"node-LatLon":{"lon":-1084706889,"lat":416388787}}},{"delta":{"node-LatLon":{"lon":-1084628972,"lat":416384031}}},{"delta":{"node-LatLon":{"lon":-1084551057,"lat":416379343}}},{"delta":{"node-LatLon":{"lon":-1084473154,"lat":416374560}}},{"delta":{"node-LatLon":{"lon":-1084399541,"lat":416370085}}},{"delta":{"node-LatLon":{"lon":-1084330227,"lat":416365845}}},{"delta":{"node-LatLon":{"lon":-1084260912,"lat":416361623}}},{"delta":{"node-LatLon":{"lon":-1084184275,"lat":416356906}}},{"delta":{"node-LatLon":{"lon":-1084107548,"lat":416353136}}},{"delta":{"node-LatLon":{"lon":-1084030065,"lat":416348811}}},{"delta":{"node-LatLon":{"lon":-1083951951,"lat":416342842}}},{"delta":{"node-LatLon":{"lon":-1083873709,"lat":416337915}}},{"delta":{"node-LatLon":{"lon":-1083796972,"lat":416333186}}},{"delta":{"node-LatLon":{"lon":-1083720234,"lat":416328459}}},{"delta":{"node-LatLon":{"lon":-1083643497,"lat":416323733}}},{"delta":{"node-LatLon":{"lon":-1083566759,"lat":416319020}}},{"delta":{"node-LatLon":{"lon":-1083489868,"lat":416316067}}},{"delta":{"node-LatLon":{"lon":-1083413019,"lat":416313460}}},{"delta":{"node-LatLon":{"lon":-1083336178,"lat":416310750}}},{"delta":{"node-LatLon":{"lon":-1083259199,"lat":416308063}}},{"delta":{"node-LatLon":{"lon":-1083182086,"lat":416305377}}},{"delta":{"node-LatLon":{"lon":-1083104978,"lat":416302622}}},{"delta":{"node-LatLon":{"lon":-1083028061,"lat":416299895}}},{"delta":{"node-LatLon":{"lon":-1082951147,"lat":416297144}}},{"delta":{"node-LatLon":{"lon":-1082873751,"lat":416296812}}},{"delta":{"node-LatLon":{"lon":-1082797210,"lat":416308158}}},{"delta":{"node-LatLon":{"lon":-1082720795,"lat":416320017}}},{"delta":{"node-LatLon":{"lon":-1082645377,"lat":416331711}}},{"delta":{"node-LatLon":{"lon":-1082607675,"lat":416337584}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"notUsed2":0,"notUsed3":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416455490,"long":-1085800440}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"notUsed":0,"notUsed1":0,"frameType":{"advisory":""},"startTime":22692}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1842,"heading":270.4,"latitude":41.1164581,"speed":32.42,"longitude":-104.8309594},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":165,"serialNumber":15594,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:16:06.891Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1842,"heading":270.15,"latitude":41.1164558,"speed":32.92,"longitude":-104.8270153},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":164,"serialNumber":15593,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:15:56.582Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1827,"heading":259.0875,"latitude":41.120215,"speed":34.06,"longitude":-104.7970612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":163,"serialNumber":15592,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:37.988Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.9,"latitude":41.1203737,"speed":34.14,"longitude":-104.7959839},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":162,"serialNumber":15591,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.384Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000C4306","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415413487,"long":-1060812632},"name":"westbound_I80_272.06_279.86_SAT-84FB2473_RC_ARLI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060824406,"lat":415424958}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415413487,"long":-1060812632}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":50}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.95,"latitude":41.1203855,"speed":34.18,"longitude":-104.7959041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":159,"serialNumber":15588,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.206Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000EA327","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416355008,"long":-1062867209},"name":"eastbound_I80_267.19_272.06_SAT-7ECE7CF3_RC_ARLI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062727519,"lat":416279817}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062690294,"lat":416271928}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062652620,"lat":416264564}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062614940,"lat":416257216}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062577255,"lat":416249886}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062539573,"lat":416242549}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062501815,"lat":416235141}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062464244,"lat":416227007}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062429289,"lat":416213939}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062398699,"lat":416195722}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062373783,"lat":416173151}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062353839,"lat":416148895}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062334576,"lat":416125335}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062315283,"lat":416101788}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062296038,"lat":416078220}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062276808,"lat":416054645}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062257093,"lat":416030536}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062236012,"lat":416006340}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062206968,"lat":415987559}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062171008,"lat":415977603}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062132565,"lat":415976300}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062093782,"lat":415976349}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416355008,"long":-1062867209}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.9,"latitude":41.1203737,"speed":34.14,"longitude":-104.7959839},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":161,"serialNumber":15590,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.285Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"00000000000010847D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415976300,"long":-1062132565},"name":"eastbound_I80_272.06_279.86_SAT-A456B6BD_RC_ARLI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060830479,"lat":415423609}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415976300,"long":-1062132565}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":258.95,"latitude":41.1203855,"speed":34.18,"longitude":-104.7959041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":160,"serialNumber":15589,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:35.285Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31631,"packetID":"0000000000000EF64E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415981013,"long":-1062070609},"name":"westbound_I80_267.19_272.06_SAT-1F82D7A2_RC_ARLI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062090421,"lat":415980971}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062129021,"lat":415980789}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415981013,"long":-1062070609}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31631}},"msgCnt":56}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1826,"heading":259.1,"latitude":41.1204147,"speed":34.18,"longitude":-104.7957042},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":158,"serialNumber":15587,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:34.686Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31632,"packetID":"0000000000000F6CF3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412309017,"long":-1054379125},"name":"eastbound_I80_323.85_325.82_SAT-0405F53D_VSL_V002136","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054387340,"lat":412253070}}},{"delta":{"node-LatLon":{"lon":-1054384188,"lat":412238776}}},{"delta":{"node-LatLon":{"lon":-1054383083,"lat":412224323}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054389797,"lat":412195863}}},{"delta":{"node-LatLon":{"lon":-1054394498,"lat":412181812}}},{"delta":{"node-LatLon":{"lon":-1054399238,"lat":412167769}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054408711,"lat":412139682}}},{"delta":{"node-LatLon":{"lon":-1054413260,"lat":412125813}}},{"delta":{"node-LatLon":{"lon":-1054415782,"lat":412111677}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054408252,"lat":412083905}}},{"delta":{"node-LatLon":{"lon":-1054400204,"lat":412070975}}},{"delta":{"node-LatLon":{"lon":-1054391746,"lat":412058198}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054370810,"lat":412034419}}},{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001110000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412309017,"long":-1054379125}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31632}},"msgCnt":21}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1823,"heading":258.9125,"latitude":41.1207321,"speed":34.16,"longitude":-104.7935083},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":157,"serialNumber":15586,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:29.216Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31632,"packetID":"0000000000000E347A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412822611,"long":-1055185238},"name":"eastbound_I80_317.68_323.85_SAT-E7615079_VSL_V002118","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054370239,"lat":412350939}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111110000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412822611,"long":-1055185238}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31632}},"msgCnt":24}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1823,"heading":258.95,"latitude":41.1208274,"speed":34.16,"longitude":-104.7928706},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":156,"serialNumber":15585,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:14:27.595Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1805,"heading":268.9125,"latitude":41.1243603,"speed":34.06,"longitude":-104.7570576},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":155,"serialNumber":15584,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:12:58.605Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1788,"heading":245.6375,"latitude":41.1273721,"speed":34.2,"longitude":-104.7257668},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":154,"serialNumber":15583,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:11:40.212Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.8125,"latitude":41.1407438,"speed":34.14,"longitude":-104.6942247},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":150,"serialNumber":15579,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:10.898Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.7625,"latitude":41.1407266,"speed":34.18,"longitude":-104.6942583},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":151,"serialNumber":15580,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:10.997Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":5}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1787,"heading":245.0375,"latitude":41.1287356,"speed":34.1,"longitude":-104.7218965},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":153,"serialNumber":15582,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:11:29.798Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1804,"heading":235.8125,"latitude":41.1406572,"speed":34.14,"longitude":-104.6943927},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":152,"serialNumber":15581,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:11.497Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:19Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":242.75,"latitude":41.1563554,"speed":27.74,"longitude":-104.6602258},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":148,"serialNumber":15577,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:08:31.690Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.7375,"latitude":41.1504085,"speed":10.58,"longitude":-104.6569867},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":145,"serialNumber":15574,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:04.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"00000000000004865E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410974214,"long":-1051103433},"name":"eastbound_I80_345.9_349.15_SAT-2D188807_VSL_V002275","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1051046217,"lat":410971780}}},{"delta":{"node-LatLon":{"lon":-1051027336,"lat":410973993}}},{"delta":{"node-LatLon":{"lon":-1051008857,"lat":410977669}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050972405,"lat":410986387}}},{"delta":{"node-LatLon":{"lon":-1050953820,"lat":410989753}}},{"delta":{"node-LatLon":{"lon":-1050934905,"lat":410991795}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050896815,"lat":410994269}}},{"delta":{"node-LatLon":{"lon":-1050877759,"lat":410995411}}},{"delta":{"node-LatLon":{"lon":-1050858673,"lat":410996615}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050820456,"lat":410998476}}},{"delta":{"node-LatLon":{"lon":-1050801305,"lat":410998519}}},{"delta":{"node-LatLon":{"lon":-1050782155,"lat":410998320}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050743855,"lat":410997929}}},{"delta":{"node-LatLon":{"lon":-1050724706,"lat":410997718}}},{"delta":{"node-LatLon":{"lon":-1050705556,"lat":410997530}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050667295,"lat":410997427}}},{"delta":{"node-LatLon":{"lon":-1050648246,"lat":410998545}}},{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050591949,"lat":411006727}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050554451,"lat":411012343}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050516970,"lat":411018025}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410974214,"long":-1051103433}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1813,"heading":235.65,"latitude":41.1425286,"speed":34.22,"longitude":-104.6907602},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":149,"serialNumber":15578,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:10:00.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1809,"heading":24.8125,"latitude":41.1514708,"speed":15.66,"longitude":-104.6561164},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":147,"serialNumber":15576,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:13.987Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":33.1625,"latitude":41.1504928,"speed":11.56,"longitude":-104.656914},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":146,"serialNumber":15575,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:05.097Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000E71AE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411217079,"long":-1052895308},"name":"eastbound_I80_336.16_339.86_SAT-3150A15C_VSL_V002214","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052878140,"lat":411209333}}},{"delta":{"node-LatLon":{"lon":-1052861535,"lat":411200909}}},{"delta":{"node-LatLon":{"lon":-1052844985,"lat":411192422}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052811861,"lat":411175478}}},{"delta":{"node-LatLon":{"lon":-1052795294,"lat":411167011}}},{"delta":{"node-LatLon":{"lon":-1052778775,"lat":411158491}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052745689,"lat":411141506}}},{"delta":{"node-LatLon":{"lon":-1052728865,"lat":411133341}}},{"delta":{"node-LatLon":{"lon":-1052712029,"lat":411126535}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052676657,"lat":411115670}}},{"delta":{"node-LatLon":{"lon":-1052658860,"lat":411110441}}},{"delta":{"node-LatLon":{"lon":-1052641069,"lat":411105200}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052605463,"lat":411094765}}},{"delta":{"node-LatLon":{"lon":-1052587658,"lat":411089552}}},{"delta":{"node-LatLon":{"lon":-1052569865,"lat":411084315}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052534102,"lat":411073877}}},{"delta":{"node-LatLon":{"lon":-1052516080,"lat":411068778}}},{"delta":{"node-LatLon":{"lon":-1052497957,"lat":411063891}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052461302,"lat":411055044}}},{"delta":{"node-LatLon":{"lon":-1052442589,"lat":411051677}}},{"delta":{"node-LatLon":{"lon":-1052423634,"lat":411049202}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052385309,"lat":411046833}}},{"delta":{"node-LatLon":{"lon":-1052366071,"lat":411046704}}},{"delta":{"node-LatLon":{"lon":-1052346951,"lat":411046651}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052308709,"lat":411046714}}},{"delta":{"node-LatLon":{"lon":-1052289589,"lat":411046568}}},{"delta":{"node-LatLon":{"lon":-1052270529,"lat":411045480}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052233174,"lat":411039476}}},{"delta":{"node-LatLon":{"lon":-1052215223,"lat":411034508}}},{"delta":{"node-LatLon":{"lon":-1052197936,"lat":411028337}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411217079,"long":-1052895308}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.65,"latitude":41.1504005,"speed":10.48,"longitude":-104.6569936},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":144,"serialNumber":15573,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.992Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"000000000000019963","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410982319,"long":-1051615463},"name":"eastbound_I80_343.24_345.9_SAT-7C287339_VSL_V002255","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}},{"delta":{"node-LatLon":{"lon":-1051560307,"lat":410993246}}},{"delta":{"node-LatLon":{"lon":-1051541730,"lat":410996259}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051503871,"lat":410998228}}},{"delta":{"node-LatLon":{"lon":-1051484919,"lat":410997224}}},{"delta":{"node-LatLon":{"lon":-1051466104,"lat":410995204}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051428300,"lat":410990965}}},{"delta":{"node-LatLon":{"lon":-1051409297,"lat":410988823}}},{"delta":{"node-LatLon":{"lon":-1051390243,"lat":410986964}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051351924,"lat":410984978}}},{"delta":{"node-LatLon":{"lon":-1051332714,"lat":410985049}}},{"delta":{"node-LatLon":{"lon":-1051313512,"lat":410985509}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051275112,"lat":410986528}}},{"delta":{"node-LatLon":{"lon":-1051255905,"lat":410986855}}},{"delta":{"node-LatLon":{"lon":-1051236694,"lat":410986784}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051198327,"lat":410985247}}},{"delta":{"node-LatLon":{"lon":-1051179211,"lat":410983796}}},{"delta":{"node-LatLon":{"lon":-1051160152,"lat":410981958}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051122310,"lat":410976921}}},{"delta":{"node-LatLon":{"lon":-1051103433,"lat":410974214}}},{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410982319,"long":-1051615463}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.75,"latitude":41.1503925,"speed":10.4,"longitude":-104.6570004},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":143,"serialNumber":15572,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.895Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000D7A5F","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411039476,"long":-1052233174},"name":"eastbound_I80_339.86_343.24_SAT-C920DC35_VSL_V002234","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052215223,"lat":411034508}}},{"delta":{"node-LatLon":{"lon":-1052197936,"lat":411028337}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052164942,"lat":411013681}}},{"delta":{"node-LatLon":{"lon":-1052148522,"lat":411006239}}},{"delta":{"node-LatLon":{"lon":-1052132112,"lat":410998785}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052099402,"lat":410983743}}},{"delta":{"node-LatLon":{"lon":-1052083431,"lat":410975763}}},{"delta":{"node-LatLon":{"lon":-1052067516,"lat":410967720}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1052032886,"lat":410955603}}},{"delta":{"node-LatLon":{"lon":-1052014286,"lat":410952254}}},{"delta":{"node-LatLon":{"lon":-1051995357,"lat":410950942}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051957579,"lat":410953842}}},{"delta":{"node-LatLon":{"lon":-1051938862,"lat":410956431}}},{"delta":{"node-LatLon":{"lon":-1051920112,"lat":410958875}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051882249,"lat":410961626}}},{"delta":{"node-LatLon":{"lon":-1051863254,"lat":410962462}}},{"delta":{"node-LatLon":{"lon":-1051844258,"lat":410963288}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051806052,"lat":410964852}}},{"delta":{"node-LatLon":{"lon":-1051786867,"lat":410965906}}},{"delta":{"node-LatLon":{"lon":-1051767713,"lat":410967235}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051729481,"lat":410970472}}},{"delta":{"node-LatLon":{"lon":-1051710370,"lat":410972125}}},{"delta":{"node-LatLon":{"lon":-1051691247,"lat":410973695}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051653026,"lat":410977005}}},{"delta":{"node-LatLon":{"lon":-1051634017,"lat":410979217}}},{"delta":{"node-LatLon":{"lon":-1051615463,"lat":410982319}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411039476,"long":-1052233174}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.8375,"latitude":41.1503846,"speed":10.24,"longitude":-104.6570069},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":142,"serialNumber":15571,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.795Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000CBE5E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411072254,"long":-1052512418},"name":"westbound_I80_338.1_334.3_SAT-6073BA35_VSL_V002226","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1052530201,"lat":411077493}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052565806,"lat":411087956}}},{"delta":{"node-LatLon":{"lon":-1052583610,"lat":411093218}}},{"delta":{"node-LatLon":{"lon":-1052601439,"lat":411098430}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052637078,"lat":411108892}}},{"delta":{"node-LatLon":{"lon":-1052654889,"lat":411114140}}},{"delta":{"node-LatLon":{"lon":-1052672710,"lat":411119370}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052708153,"lat":411130194}}},{"delta":{"node-LatLon":{"lon":-1052725070,"lat":411136916}}},{"delta":{"node-LatLon":{"lon":-1052741814,"lat":411145056}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052774845,"lat":411161873}}},{"delta":{"node-LatLon":{"lon":-1052791339,"lat":411170306}}},{"delta":{"node-LatLon":{"lon":-1052807830,"lat":411178743}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052840856,"lat":411195568}}},{"delta":{"node-LatLon":{"lon":-1052857346,"lat":411204006}}},{"delta":{"node-LatLon":{"lon":-1052873972,"lat":411212287}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052908476,"lat":411226105}}},{"delta":{"node-LatLon":{"lon":-1052926265,"lat":411231492}}},{"delta":{"node-LatLon":{"lon":-1052944495,"lat":411235952}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1052981949,"lat":411242012}}},{"delta":{"node-LatLon":{"lon":-1053000858,"lat":411244369}}},{"delta":{"node-LatLon":{"lon":-1053019776,"lat":411246688}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}},{"delta":{"node-LatLon":{"lon":-1053076521,"lat":411253681}}},{"delta":{"node-LatLon":{"lon":-1053095502,"lat":411255432}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053133604,"lat":411258022}}},{"delta":{"node-LatLon":{"lon":-1053152654,"lat":411259322}}},{"delta":{"node-LatLon":{"lon":-1053171705,"lat":411260611}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053209808,"lat":411263198}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411072254,"long":-1052512418}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.9375,"latitude":41.150377,"speed":10.18,"longitude":-104.6570136},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":141,"serialNumber":15570,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.795Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"000000000000025AF6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410964119,"long":-1051880840},"name":"westbound_I80_341.6_338.1_SAT-540A458A_VSL_V002247","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051918620,"lat":410961452}}},{"delta":{"node-LatLon":{"lon":-1051937339,"lat":410959095}}},{"delta":{"node-LatLon":{"lon":-1051956011,"lat":410956529}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1051993632,"lat":410953204}}},{"delta":{"node-LatLon":{"lon":-1052012535,"lat":410954343}}},{"delta":{"node-LatLon":{"lon":-1052031026,"lat":410957479}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052065392,"lat":410969376}}},{"delta":{"node-LatLon":{"lon":-1052081156,"lat":410977355}}},{"delta":{"node-LatLon":{"lon":-1052097000,"lat":410985243}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052129309,"lat":411000279}}},{"delta":{"node-LatLon":{"lon":-1052145586,"lat":411007645}}},{"delta":{"node-LatLon":{"lon":-1052161846,"lat":411015033}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052194841,"lat":411029703}}},{"delta":{"node-LatLon":{"lon":-1052212178,"lat":411036116}}},{"delta":{"node-LatLon":{"lon":-1052230242,"lat":411041252}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052267858,"lat":411047647}}},{"delta":{"node-LatLon":{"lon":-1052287100,"lat":411048748}}},{"delta":{"node-LatLon":{"lon":-1052306402,"lat":411048858}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052345008,"lat":411049101}}},{"delta":{"node-LatLon":{"lon":-1052364312,"lat":411049135}}},{"delta":{"node-LatLon":{"lon":-1052383393,"lat":411049206}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052421426,"lat":411051319}}},{"delta":{"node-LatLon":{"lon":-1052440234,"lat":411053738}}},{"delta":{"node-LatLon":{"lon":-1052458744,"lat":411057225}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052494624,"lat":411067040}}},{"delta":{"node-LatLon":{"lon":-1052512418,"lat":411072254}}},{"delta":{"node-LatLon":{"lon":-1052530201,"lat":411077493}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410964119,"long":-1051880840}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":32.9375,"latitude":41.150377,"speed":10.18,"longitude":-104.6570136},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":140,"serialNumber":15569,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"00000000000001F426","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410988342,"long":-1051297925},"name":"westbound_I80_344.69_341.6_SAT-0D253AC5_VSL_V002266","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}},{"delta":{"node-LatLon":{"lon":-1051353366,"lat":410987336}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051390245,"lat":410989287}}},{"delta":{"node-LatLon":{"lon":-1051408562,"lat":410991189}}},{"delta":{"node-LatLon":{"lon":-1051426852,"lat":410993239}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051464077,"lat":410997440}}},{"delta":{"node-LatLon":{"lon":-1051483045,"lat":410999413}}},{"delta":{"node-LatLon":{"lon":-1051502129,"lat":411000540}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051540305,"lat":410998837}}},{"delta":{"node-LatLon":{"lon":-1051559069,"lat":410995977}}},{"delta":{"node-LatLon":{"lon":-1051577615,"lat":410992374}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051614630,"lat":410984946}}},{"delta":{"node-LatLon":{"lon":-1051633310,"lat":410981780}}},{"delta":{"node-LatLon":{"lon":-1051652234,"lat":410979420}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051690345,"lat":410976089}}},{"delta":{"node-LatLon":{"lon":-1051709415,"lat":410974522}}},{"delta":{"node-LatLon":{"lon":-1051728480,"lat":410972919}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051766615,"lat":410969748}}},{"delta":{"node-LatLon":{"lon":-1051785706,"lat":410968344}}},{"delta":{"node-LatLon":{"lon":-1051804844,"lat":410967360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051842945,"lat":410965770}}},{"delta":{"node-LatLon":{"lon":-1051861895,"lat":410964974}}},{"delta":{"node-LatLon":{"lon":-1051880840,"lat":410964119}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410988342,"long":-1051297925}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":17}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531237,"speed":0.02,"longitude":-104.6592302},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":137,"serialNumber":15566,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:05:45.221Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":33.15,"latitude":41.1503693,"speed":10.08,"longitude":-104.6570203},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":139,"serialNumber":15568,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:03.695Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31624,"packetID":"0000000000000AB37E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411002479,"long":-1050722393},"name":"westbound_I80_347.69_344.69_SAT-3E628AB0_VSL_V002290","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050741574,"lat":411002681}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050779937,"lat":411002969}}},{"delta":{"node-LatLon":{"lon":-1050799110,"lat":411002558}}},{"delta":{"node-LatLon":{"lon":-1050818249,"lat":411001589}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050856482,"lat":410999179}}},{"delta":{"node-LatLon":{"lon":-1050875598,"lat":410997967}}},{"delta":{"node-LatLon":{"lon":-1050895063,"lat":410996770}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050933978,"lat":410994246}}},{"delta":{"node-LatLon":{"lon":-1050953322,"lat":410992263}}},{"delta":{"node-LatLon":{"lon":-1050972317,"lat":410988851}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051009569,"lat":410979971}}},{"delta":{"node-LatLon":{"lon":-1051028444,"lat":410976198}}},{"delta":{"node-LatLon":{"lon":-1051047752,"lat":410974038}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051086711,"lat":410974535}}},{"delta":{"node-LatLon":{"lon":-1051105965,"lat":410976959}}},{"delta":{"node-LatLon":{"lon":-1051125148,"lat":410979701}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051163659,"lat":410984549}}},{"delta":{"node-LatLon":{"lon":-1051183016,"lat":410986460}}},{"delta":{"node-LatLon":{"lon":-1051202450,"lat":410987845}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051241445,"lat":410989249}}},{"delta":{"node-LatLon":{"lon":-1051260967,"lat":410989237}}},{"delta":{"node-LatLon":{"lon":-1051279448,"lat":410988854}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411002479,"long":-1050722393}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31624}},"msgCnt":13}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":35.525,"latitude":41.1502985,"speed":8.76,"longitude":-104.6570835},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":138,"serialNumber":15567,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:07:02.689Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531242,"speed":0.02,"longitude":-104.6592305},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":136,"serialNumber":15565,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:05:33.701Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531244,"speed":0.02,"longitude":-104.6592302},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":135,"serialNumber":15564,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:04:35.702Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1808,"heading":251.0625,"latitude":41.1531259,"speed":0.02,"longitude":-104.659231},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":134,"serialNumber":15563,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:04:24.119Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":251.0625,"latitude":41.1531274,"speed":0.02,"longitude":-104.6592349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":133,"serialNumber":15562,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T23:00:21.777Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1821,"heading":55.6625,"latitude":41.1432762,"speed":33.68,"longitude":-104.6883421},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":132,"serialNumber":15561,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:06.352Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000B4F4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411246688,"long":-1053019776},"name":"westbound_I80_323.05_335.11_SAT-B91A2E52_RC_LARI80ECHEYBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054127454,"lat":411694572}}},{"delta":{"node-LatLon":{"lon":-1054164403,"lat":411745737}}},{"delta":{"node-LatLon":{"lon":-1054200041,"lat":411796105}}},{"delta":{"node-LatLon":{"lon":-1054218886,"lat":411851211}}},{"delta":{"node-LatLon":{"lon":-1054243815,"lat":411905185}}},{"delta":{"node-LatLon":{"lon":-1054287780,"lat":411952905}}},{"delta":{"node-LatLon":{"lon":-1054331852,"lat":412000578}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000001111}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411246688,"long":-1053019776}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5127}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1821,"heading":55.6,"latitude":41.143259,"speed":33.66,"longitude":-104.6883751},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":131,"serialNumber":15560,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:06.352Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000F25D6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412420501,"long":-1054392109},"name":"eastbound_I80_323.05_335.11_SAT-2FAB6C57_RC_LARI80ECHEYBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111110000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412420501,"long":-1054392109}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5127}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1820,"heading":55.65,"latitude":41.1429505,"speed":33.72,"longitude":-104.6889711},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":130,"serialNumber":15559,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:04.456Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"0000000000000936E7","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417414634,"long":-1068269969},"name":"westbound_I80_221.2_235.23_SAT-09D8678A_RC_RAWI80ELARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068289321,"lat":417415359}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}},{"delta":{"node-LatLon":{"lon":-1068385974,"lat":417418859}}},{"delta":{"node-LatLon":{"lon":-1068463156,"lat":417421689}}},{"delta":{"node-LatLon":{"lon":-1068540338,"lat":417424515}}},{"delta":{"node-LatLon":{"lon":-1068617852,"lat":417427395}}},{"delta":{"node-LatLon":{"lon":-1068695369,"lat":417430231}}},{"delta":{"node-LatLon":{"lon":-1068772890,"lat":417433050}}},{"delta":{"node-LatLon":{"lon":-1068850417,"lat":417435830}}},{"delta":{"node-LatLon":{"lon":-1068927943,"lat":417438632}}},{"delta":{"node-LatLon":{"lon":-1069005025,"lat":417441424}}},{"delta":{"node-LatLon":{"lon":-1069082106,"lat":417444219}}},{"delta":{"node-LatLon":{"lon":-1069159408,"lat":417446974}}},{"delta":{"node-LatLon":{"lon":-1069236759,"lat":417451306}}},{"delta":{"node-LatLon":{"lon":-1069312011,"lat":417465173}}},{"delta":{"node-LatLon":{"lon":-1069385103,"lat":417484568}}},{"delta":{"node-LatLon":{"lon":-1069458135,"lat":417504094}}},{"delta":{"node-LatLon":{"lon":-1069530060,"lat":417523167}}},{"delta":{"node-LatLon":{"lon":-1069600849,"lat":417541844}}},{"delta":{"node-LatLon":{"lon":-1069673525,"lat":417555795}}},{"delta":{"node-LatLon":{"lon":-1069748966,"lat":417568966}}},{"delta":{"node-LatLon":{"lon":-1069824418,"lat":417582109}}},{"delta":{"node-LatLon":{"lon":-1069899351,"lat":417595155}}},{"delta":{"node-LatLon":{"lon":-1069973766,"lat":417608100}}},{"delta":{"node-LatLon":{"lon":-1070048170,"lat":417621086}}},{"delta":{"node-LatLon":{"lon":-1070123773,"lat":417634264}}},{"delta":{"node-LatLon":{"lon":-1070199399,"lat":417647374}}},{"delta":{"node-LatLon":{"lon":-1070274965,"lat":417660512}}},{"delta":{"node-LatLon":{"lon":-1070350472,"lat":417673678}}},{"delta":{"node-LatLon":{"lon":-1070425989,"lat":417686813}}},{"delta":{"node-LatLon":{"lon":-1070501711,"lat":417699947}}},{"delta":{"node-LatLon":{"lon":-1070577425,"lat":417713109}}},{"delta":{"node-LatLon":{"lon":-1070653637,"lat":417726293}}},{"delta":{"node-LatLon":{"lon":-1070730992,"lat":417736504}}},{"delta":{"node-LatLon":{"lon":-1070808409,"lat":417727589}}},{"delta":{"node-LatLon":{"lon":-1070884161,"lat":417718392}}},{"delta":{"node-LatLon":{"lon":-1070959940,"lat":417729715}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417414634,"long":-1068269969}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":34}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1819,"heading":55.6625,"latitude":41.1429333,"speed":33.7,"longitude":-104.6890041},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":129,"serialNumber":15558,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:53:04.456Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31610,"packetID":"00000000000009698C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417730521,"long":-1070980675},"name":"eastbound_I80_221.2_235.23_SAT-BA88D691_RC_RAWI80ELARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1070961677,"lat":417727641}}},{"delta":{"node-LatLon":{"lon":-1070885649,"lat":417716362}}},{"delta":{"node-LatLon":{"lon":-1070809626,"lat":417725169}}},{"delta":{"node-LatLon":{"lon":-1070732756,"lat":417733042}}},{"delta":{"node-LatLon":{"lon":-1070656229,"lat":417722191}}},{"delta":{"node-LatLon":{"lon":-1070580490,"lat":417709023}}},{"delta":{"node-LatLon":{"lon":-1070504992,"lat":417695900}}},{"delta":{"node-LatLon":{"lon":-1070429493,"lat":417682786}}},{"delta":{"node-LatLon":{"lon":-1070354047,"lat":417669673}}},{"delta":{"node-LatLon":{"lon":-1070278596,"lat":417656581}}},{"delta":{"node-LatLon":{"lon":-1070202954,"lat":417643413}}},{"delta":{"node-LatLon":{"lon":-1070127097,"lat":417630244}}},{"delta":{"node-LatLon":{"lon":-1070051256,"lat":417617028}}},{"delta":{"node-LatLon":{"lon":-1069975759,"lat":417603852}}},{"delta":{"node-LatLon":{"lon":-1069900250,"lat":417590719}}},{"delta":{"node-LatLon":{"lon":-1069825529,"lat":417577695}}},{"delta":{"node-LatLon":{"lon":-1069751604,"lat":417564757}}},{"delta":{"node-LatLon":{"lon":-1069677665,"lat":417551870}}},{"delta":{"node-LatLon":{"lon":-1069603910,"lat":417538967}}},{"delta":{"node-LatLon":{"lon":-1069531945,"lat":417521380}}},{"delta":{"node-LatLon":{"lon":-1069460002,"lat":417502274}}},{"delta":{"node-LatLon":{"lon":-1069387530,"lat":417482961}}},{"delta":{"node-LatLon":{"lon":-1069315049,"lat":417463671}}},{"delta":{"node-LatLon":{"lon":-1069240161,"lat":417448143}}},{"delta":{"node-LatLon":{"lon":-1069162781,"lat":417442613}}},{"delta":{"node-LatLon":{"lon":-1069085198,"lat":417439823}}},{"delta":{"node-LatLon":{"lon":-1069007744,"lat":417437041}}},{"delta":{"node-LatLon":{"lon":-1068930291,"lat":417434237}}},{"delta":{"node-LatLon":{"lon":-1068853004,"lat":417431463}}},{"delta":{"node-LatLon":{"lon":-1068775721,"lat":417428637}}},{"delta":{"node-LatLon":{"lon":-1068698384,"lat":417425830}}},{"delta":{"node-LatLon":{"lon":-1068620993,"lat":417423054}}},{"delta":{"node-LatLon":{"lon":-1068543604,"lat":417420239}}},{"delta":{"node-LatLon":{"lon":-1068465827,"lat":417417448}}},{"delta":{"node-LatLon":{"lon":-1068388058,"lat":417414571}}},{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068291290,"lat":417411033}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417730521,"long":-1070980675}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31610}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1813,"heading":55.8,"latitude":41.1416528,"speed":33.86,"longitude":-104.6915031},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":128,"serialNumber":15557,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:52:56.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1785,"heading":64.5,"latitude":41.1294943,"speed":33.72,"longitude":-104.7183663},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":127,"serialNumber":15556,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:38.659Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1785,"heading":64.4875,"latitude":41.129429,"speed":33.72,"longitude":-104.7185478},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":126,"serialNumber":15555,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:38.064Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1786,"heading":64.4,"latitude":41.1281042,"speed":33.72,"longitude":-104.7222965},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":125,"serialNumber":15554,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:51:27.862Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1810,"heading":83.2375,"latitude":41.1237719,"speed":33.74,"longitude":-104.7710343},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":124,"serialNumber":15553,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:49:24.469Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1812,"heading":79.025,"latitude":41.1232447,"speed":33.74,"longitude":-104.7751515},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":123,"serialNumber":15552,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:49:14.272Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1847,"heading":78.975,"latitude":41.1169477,"speed":32.36,"longitude":-104.8182828},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":122,"serialNumber":15551,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:47:24.575Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1845,"heading":77.7,"latitude":41.1159012,"speed":34,"longitude":-104.8409627},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":121,"serialNumber":15550,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:46:27.777Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1849,"heading":73.9,"latitude":41.1149888,"speed":33.66,"longitude":-104.8452745},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":120,"serialNumber":15549,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:46:16.678Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1906,"heading":89.55,"latitude":41.116473,"speed":33.74,"longitude":-104.8918353},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":119,"serialNumber":15548,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:44:17.473Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1934,"heading":81.9125,"latitude":41.1133295,"speed":33.72,"longitude":-104.928415},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":118,"serialNumber":15547,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:42:45.469Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1935,"heading":81.8375,"latitude":41.112875,"speed":33.74,"longitude":-104.9328746},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":117,"serialNumber":15546,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:42:34.275Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":1974,"heading":84.1875,"latitude":41.1097147,"speed":33.74,"longitude":-104.9682881},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":116,"serialNumber":15545,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:41:05.380Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2012,"heading":69.7125,"latitude":41.1052636,"speed":33.68,"longitude":-104.9975033},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":115,"serialNumber":15544,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:50.989Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2013,"heading":69.6,"latitude":41.1051793,"speed":33.7,"longitude":-104.9978043},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":114,"serialNumber":15543,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:50.295Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2023,"heading":69.3,"latitude":41.1036902,"speed":33.84,"longitude":-105.0030723},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":113,"serialNumber":15542,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:39:36.288Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2067,"heading":88.15,"latitude":41.103157,"speed":32.74,"longitude":-105.0380418},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":112,"serialNumber":15541,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:38:06.906Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2101,"heading":89.1625,"latitude":41.0997427,"speed":29.06,"longitude":-105.0669513},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":111,"serialNumber":15540,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:36:43.704Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2106,"heading":90.6,"latitude":41.0997719,"speed":29.24,"longitude":-105.072266},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":110,"serialNumber":15539,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:36:28.405Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2156,"heading":92.55,"latitude":41.0978479,"speed":18.52,"longitude":-105.114164},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":109,"serialNumber":15538,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:34:24.894Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.7,"latitude":41.0973887,"speed":29.26,"longitude":-105.1050253},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":108,"serialNumber":15537,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.398Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525486,"packetID":"0000000000000A59C2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410988342,"long":-1051297925},"name":"westbound_I80_344.69_341.6_RSU-10.145.13.73_VSL_V002266","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}},{"delta":{"node-LatLon":{"lon":-1051353366,"lat":410987336}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051390245,"lat":410989287}}},{"delta":{"node-LatLon":{"lon":-1051408562,"lat":410991189}}},{"delta":{"node-LatLon":{"lon":-1051426852,"lat":410993239}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051464077,"lat":410997440}}},{"delta":{"node-LatLon":{"lon":-1051483045,"lat":410999413}}},{"delta":{"node-LatLon":{"lon":-1051502129,"lat":411000540}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051540305,"lat":410998837}}},{"delta":{"node-LatLon":{"lon":-1051559069,"lat":410995977}}},{"delta":{"node-LatLon":{"lon":-1051577615,"lat":410992374}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051614630,"lat":410984946}}},{"delta":{"node-LatLon":{"lon":-1051633310,"lat":410981780}}},{"delta":{"node-LatLon":{"lon":-1051652234,"lat":410979420}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051690345,"lat":410976089}}},{"delta":{"node-LatLon":{"lon":-1051709415,"lat":410974522}}},{"delta":{"node-LatLon":{"lon":-1051728480,"lat":410972919}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051766615,"lat":410969748}}},{"delta":{"node-LatLon":{"lon":-1051785706,"lat":410968344}}},{"delta":{"node-LatLon":{"lon":-1051804844,"lat":410967360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051842945,"lat":410965770}}},{"delta":{"node-LatLon":{"lon":-1051861895,"lat":410964974}}},{"delta":{"node-LatLon":{"lon":-1051880840,"lat":410964119}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410988342,"long":-1051297925}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":525486}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.4125,"latitude":41.0973906,"speed":29.22,"longitude":-105.1049903},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":107,"serialNumber":15536,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.298Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525488,"packetID":"000000000000095E23","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410982319,"long":-1051615463},"name":"eastbound_I80_343.24_345.9_RSU-10.145.13.73_VSL_V002255","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051578694,"lat":410989607}}},{"delta":{"node-LatLon":{"lon":-1051560307,"lat":410993246}}},{"delta":{"node-LatLon":{"lon":-1051541730,"lat":410996259}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051503871,"lat":410998228}}},{"delta":{"node-LatLon":{"lon":-1051484919,"lat":410997224}}},{"delta":{"node-LatLon":{"lon":-1051466104,"lat":410995204}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051428300,"lat":410990965}}},{"delta":{"node-LatLon":{"lon":-1051409297,"lat":410988823}}},{"delta":{"node-LatLon":{"lon":-1051390243,"lat":410986964}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051351924,"lat":410984978}}},{"delta":{"node-LatLon":{"lon":-1051332714,"lat":410985049}}},{"delta":{"node-LatLon":{"lon":-1051313512,"lat":410985509}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051275112,"lat":410986528}}},{"delta":{"node-LatLon":{"lon":-1051255905,"lat":410986855}}},{"delta":{"node-LatLon":{"lon":-1051236694,"lat":410986784}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051198327,"lat":410985247}}},{"delta":{"node-LatLon":{"lon":-1051179211,"lat":410983796}}},{"delta":{"node-LatLon":{"lon":-1051160152,"lat":410981958}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051122310,"lat":410976921}}},{"delta":{"node-LatLon":{"lon":-1051103433,"lat":410974214}}},{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410982319,"long":-1051615463}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":525488}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.4125,"latitude":41.0973927,"speed":29.22,"longitude":-105.1049556},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":106,"serialNumber":15535,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.202Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525489,"packetID":"000000000000075900","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410974214,"long":-1051103433},"name":"eastbound_I80_345.9_349.15_RSU-10.145.13.73_VSL_V002275","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1051084469,"lat":410971913}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1051046217,"lat":410971780}}},{"delta":{"node-LatLon":{"lon":-1051027336,"lat":410973993}}},{"delta":{"node-LatLon":{"lon":-1051008857,"lat":410977669}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050972405,"lat":410986387}}},{"delta":{"node-LatLon":{"lon":-1050953820,"lat":410989753}}},{"delta":{"node-LatLon":{"lon":-1050934905,"lat":410991795}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050896815,"lat":410994269}}},{"delta":{"node-LatLon":{"lon":-1050877759,"lat":410995411}}},{"delta":{"node-LatLon":{"lon":-1050858673,"lat":410996615}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050820456,"lat":410998476}}},{"delta":{"node-LatLon":{"lon":-1050801305,"lat":410998519}}},{"delta":{"node-LatLon":{"lon":-1050782155,"lat":410998320}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050743855,"lat":410997929}}},{"delta":{"node-LatLon":{"lon":-1050724706,"lat":410997718}}},{"delta":{"node-LatLon":{"lon":-1050705556,"lat":410997530}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050667295,"lat":410997427}}},{"delta":{"node-LatLon":{"lon":-1050648246,"lat":410998545}}},{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050591949,"lat":411006727}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050554451,"lat":411012343}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050516970,"lat":411018025}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410974214,"long":-1051103433}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":525489}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.1625,"latitude":41.0973947,"speed":29.22,"longitude":-105.1049209},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":105,"serialNumber":15534,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.102Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525489,"packetID":"0000000000000B442E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411020862,"long":-1050498229},"name":"eastbound_I80_349.15_353.5_RSU-10.145.13.73_VSL_V002299","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050479271,"lat":411023677}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}},{"delta":{"node-LatLon":{"lon":-1050441324,"lat":411029165}}},{"delta":{"node-LatLon":{"lon":-1050422091,"lat":411030485}}},{"delta":{"node-LatLon":{"lon":-1050402781,"lat":411030948}}},{"delta":{"node-LatLon":{"lon":-1050383473,"lat":411031428}}},{"delta":{"node-LatLon":{"lon":-1050364161,"lat":411031843}}},{"delta":{"node-LatLon":{"lon":-1050344848,"lat":411031826}}},{"delta":{"node-LatLon":{"lon":-1050325631,"lat":411030376}}},{"delta":{"node-LatLon":{"lon":-1050306653,"lat":411027659}}},{"delta":{"node-LatLon":{"lon":-1050288159,"lat":411024603}}},{"delta":{"node-LatLon":{"lon":-1050269678,"lat":411021507}}},{"delta":{"node-LatLon":{"lon":-1050251179,"lat":411018469}}},{"delta":{"node-LatLon":{"lon":-1050232676,"lat":411015448}}},{"delta":{"node-LatLon":{"lon":-1050214174,"lat":411012425}}},{"delta":{"node-LatLon":{"lon":-1050195535,"lat":411009957}}},{"delta":{"node-LatLon":{"lon":-1050176673,"lat":411008812}}},{"delta":{"node-LatLon":{"lon":-1050157751,"lat":411008904}}},{"delta":{"node-LatLon":{"lon":-1050138924,"lat":411010341}}},{"delta":{"node-LatLon":{"lon":-1050120335,"lat":411013008}}},{"delta":{"node-LatLon":{"lon":-1050102002,"lat":411016953}}},{"delta":{"node-LatLon":{"lon":-1050084082,"lat":411021875}}},{"delta":{"node-LatLon":{"lon":-1050066198,"lat":411026874}}},{"delta":{"node-LatLon":{"lon":-1050048325,"lat":411031899}}},{"delta":{"node-LatLon":{"lon":-1050030476,"lat":411036969}}},{"delta":{"node-LatLon":{"lon":-1050012604,"lat":411041995}}},{"delta":{"node-LatLon":{"lon":-1049994738,"lat":411047033}}},{"delta":{"node-LatLon":{"lon":-1049976865,"lat":411052057}}},{"delta":{"node-LatLon":{"lon":-1049959011,"lat":411057120}}},{"delta":{"node-LatLon":{"lon":-1049941141,"lat":411062151}}},{"delta":{"node-LatLon":{"lon":-1049923053,"lat":411066918}}},{"delta":{"node-LatLon":{"lon":-1049904488,"lat":411070470}}},{"delta":{"node-LatLon":{"lon":-1049885607,"lat":411072913}}},{"delta":{"node-LatLon":{"lon":-1049866692,"lat":411075206}}},{"delta":{"node-LatLon":{"lon":-1049847778,"lat":411077504}}},{"delta":{"node-LatLon":{"lon":-1049828870,"lat":411079830}}},{"delta":{"node-LatLon":{"lon":-1049809945,"lat":411082077}}},{"delta":{"node-LatLon":{"lon":-1049791039,"lat":411084415}}},{"delta":{"node-LatLon":{"lon":-1049772121,"lat":411086693}}},{"delta":{"node-LatLon":{"lon":-1049753209,"lat":411089002}}},{"delta":{"node-LatLon":{"lon":-1049734291,"lat":411091274}}},{"delta":{"node-LatLon":{"lon":-1049715382,"lat":411093589}}},{"delta":{"node-LatLon":{"lon":-1049696453,"lat":411095807}}},{"delta":{"node-LatLon":{"lon":-1049677431,"lat":411097499}}},{"delta":{"node-LatLon":{"lon":-1049658348,"lat":411098753}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411020862,"long":-1050498229}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":525489}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"RSU","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":265.1625,"latitude":41.097397,"speed":29.22,"longitude":-105.1048863},"rxSource":"RSU"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":104,"serialNumber":15533,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:13.102Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":525486,"packetID":"000000000000026E43","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411002479,"long":-1050722393},"name":"westbound_I80_347.69_344.69_RSU-10.145.13.73_VSL_V002290","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050741574,"lat":411002681}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050779937,"lat":411002969}}},{"delta":{"node-LatLon":{"lon":-1050799110,"lat":411002558}}},{"delta":{"node-LatLon":{"lon":-1050818249,"lat":411001589}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050856482,"lat":410999179}}},{"delta":{"node-LatLon":{"lon":-1050875598,"lat":410997967}}},{"delta":{"node-LatLon":{"lon":-1050895063,"lat":410996770}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050933978,"lat":410994246}}},{"delta":{"node-LatLon":{"lon":-1050953322,"lat":410992263}}},{"delta":{"node-LatLon":{"lon":-1050972317,"lat":410988851}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051009569,"lat":410979971}}},{"delta":{"node-LatLon":{"lon":-1051028444,"lat":410976198}}},{"delta":{"node-LatLon":{"lon":-1051047752,"lat":410974038}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051086711,"lat":410974535}}},{"delta":{"node-LatLon":{"lon":-1051105965,"lat":410976959}}},{"delta":{"node-LatLon":{"lon":-1051125148,"lat":410979701}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051163659,"lat":410984549}}},{"delta":{"node-LatLon":{"lon":-1051183016,"lat":410986460}}},{"delta":{"node-LatLon":{"lon":-1051202450,"lat":410987845}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051241445,"lat":410989249}}},{"delta":{"node-LatLon":{"lon":-1051260967,"lat":410989237}}},{"delta":{"node-LatLon":{"lon":-1051279448,"lat":410988854}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051316401,"lat":410987822}}},{"delta":{"node-LatLon":{"lon":-1051334880,"lat":410987346}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411002479,"long":-1050722393}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":525486}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":263.275,"latitude":41.0974419,"speed":29.16,"longitude":-105.1042981},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":103,"serialNumber":15532,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:11.398Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2147,"heading":262.5375,"latitude":41.0974641,"speed":29.2,"longitude":-105.1040569},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":102,"serialNumber":15531,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:33:10.599Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2066,"heading":268.2875,"latitude":41.1036482,"speed":33.28,"longitude":-105.0369024},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":99,"serialNumber":15528,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:30:09.661Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31494,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31494}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2149,"heading":252.35,"latitude":41.0983605,"speed":29.5,"longitude":-105.0994445},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":101,"serialNumber":15530,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:32:56.892Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2100,"heading":269.9,"latitude":41.1002133,"speed":33.28,"longitude":-105.0674061},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":100,"serialNumber":15529,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:31:27.899Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2062,"heading":278.05,"latitude":41.1035285,"speed":32.36,"longitude":-105.0326251},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":98,"serialNumber":15527,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:29:58.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2044,"heading":102.4,"latitude":41.1010291,"speed":29.68,"longitude":-105.0199132},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":97,"serialNumber":15526,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:28:29.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":521096,"packetID":"0000000000000D1DE9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411471325,"long":-1046807852},"name":"eastbound_I-80_369.0_370.0_SAT-35E16D57_RW_4794%BUFF0","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046791998,"lat":411479473}}},{"delta":{"node-LatLon":{"lon":-1046776252,"lat":411487602}}},{"delta":{"node-LatLon":{"lon":-1046760496,"lat":411495722}}},{"delta":{"node-LatLon":{"lon":-1046744707,"lat":411503803}}},{"delta":{"node-LatLon":{"lon":-1046728753,"lat":411511697}}},{"delta":{"node-LatLon":{"lon":-1046712447,"lat":411519168}}},{"delta":{"node-LatLon":{"lon":-1046695838,"lat":411526248}}},{"delta":{"node-LatLon":{"lon":-1046678980,"lat":411532982}}},{"delta":{"node-LatLon":{"lon":-1046661836,"lat":411539290}}},{"delta":{"node-LatLon":{"lon":-1046644437,"lat":411545186}}},{"delta":{"node-LatLon":{"lon":-1046626808,"lat":411550674}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":1440,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411471325,"long":-1046807852}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":777}},{"item":{"itis":13579}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":510180}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025307,"speed":24.46,"longitude":-105.0468926},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":96,"serialNumber":15525,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000F6380","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"Temp","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":4868}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":3}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025263,"speed":24.46,"longitude":-105.0469211},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":94,"serialNumber":15523,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31532,"packetID":"0000000000000D4252","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412846200,"long":-1055207674},"name":"eastbound_I80_317.45_323.05_SAT-5AFFFEF8_RC_LARI80ECHEYI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055196465,"lat":412834401}}},{"delta":{"node-LatLon":{"lon":-1055185238,"lat":412822611}}},{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055162838,"lat":412799002}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055139485,"lat":412775945}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055111710,"lat":412756134}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055080126,"lat":412740115}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055046853,"lat":412726244}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1055009981,"lat":412719587}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054972006,"lat":412717639}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054934016,"lat":412716179}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054896123,"lat":412717322}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054858665,"lat":412722173}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054822378,"lat":412715508}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054795466,"lat":412695384}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054770097,"lat":412673836}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054738855,"lat":412657720}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054700821,"lat":412654615}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054664843,"lat":412645844}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054634409,"lat":412628251}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054599367,"lat":412616899}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054566302,"lat":412602767}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054536736,"lat":412584610}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054507197,"lat":412566427}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054478373,"lat":412547636}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054457123,"lat":412523979}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054440857,"lat":412498114}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054424622,"lat":412472238}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054408332,"lat":412446382}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054392109,"lat":412420501}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054379237,"lat":412393551}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412846200,"long":-1055207674}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31532}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025307,"speed":24.46,"longitude":-105.0468926},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":95,"serialNumber":15524,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31534,"packetID":"0000000000000BF552","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412378541,"long":-1054372542},"name":"westbound_I80_317.45_323.05_SAT-7D6DFE3D_RC_LARI80ECHEYD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}},{"delta":{"node-LatLon":{"lon":-1054421149,"lat":412472313}}},{"delta":{"node-LatLon":{"lon":-1054429340,"lat":412485351}}},{"delta":{"node-LatLon":{"lon":-1054437555,"lat":412498379}}},{"delta":{"node-LatLon":{"lon":-1054445744,"lat":412511417}}},{"delta":{"node-LatLon":{"lon":-1054453974,"lat":412524441}}},{"delta":{"node-LatLon":{"lon":-1054463289,"lat":412537025}}},{"delta":{"node-LatLon":{"lon":-1054475122,"lat":412548474}}},{"delta":{"node-LatLon":{"lon":-1054489160,"lat":412558405}}},{"delta":{"node-LatLon":{"lon":-1054504069,"lat":412567600}}},{"delta":{"node-LatLon":{"lon":-1054519000,"lat":412576776}}},{"delta":{"node-LatLon":{"lon":-1054533896,"lat":412585985}}},{"delta":{"node-LatLon":{"lon":-1054548833,"lat":412595156}}},{"delta":{"node-LatLon":{"lon":-1054563820,"lat":412604280}}},{"delta":{"node-LatLon":{"lon":-1054579779,"lat":412612388}}},{"delta":{"node-LatLon":{"lon":-1054597055,"lat":412618777}}},{"delta":{"node-LatLon":{"lon":-1054615114,"lat":412623812}}},{"delta":{"node-LatLon":{"lon":-1054632271,"lat":412629637}}},{"delta":{"node-LatLon":{"lon":-1054647306,"lat":412638180}}},{"delta":{"node-LatLon":{"lon":-1054662004,"lat":412647078}}},{"delta":{"node-LatLon":{"lon":-1054678467,"lat":412653902}}},{"delta":{"node-LatLon":{"lon":-1054696868,"lat":412656761}}},{"delta":{"node-LatLon":{"lon":-1054715678,"lat":412657581}}},{"delta":{"node-LatLon":{"lon":-1054734355,"lat":412659287}}},{"delta":{"node-LatLon":{"lon":-1054751683,"lat":412664718}}},{"delta":{"node-LatLon":{"lon":-1054765976,"lat":412673917}}},{"delta":{"node-LatLon":{"lon":-1054778503,"lat":412684544}}},{"delta":{"node-LatLon":{"lon":-1054791379,"lat":412695492}}},{"delta":{"node-LatLon":{"lon":-1054804278,"lat":412706425}}},{"delta":{"node-LatLon":{"lon":-1054818479,"lat":412716349}}},{"delta":{"node-LatLon":{"lon":-1054835859,"lat":412722690}}},{"delta":{"node-LatLon":{"lon":-1054854996,"lat":412724695}}},{"delta":{"node-LatLon":{"lon":-1054874196,"lat":412722759}}},{"delta":{"node-LatLon":{"lon":-1054893260,"lat":412720064}}},{"delta":{"node-LatLon":{"lon":-1054912492,"lat":412718274}}},{"delta":{"node-LatLon":{"lon":-1054931875,"lat":412718613}}},{"delta":{"node-LatLon":{"lon":-1054951253,"lat":412719209}}},{"delta":{"node-LatLon":{"lon":-1054969662,"lat":412719789}}},{"delta":{"node-LatLon":{"lon":-1054987987,"lat":412721117}}},{"delta":{"node-LatLon":{"lon":-1055005745,"lat":412724757}}},{"delta":{"node-LatLon":{"lon":-1055022420,"lat":412730636}}},{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412378541,"long":-1054372542}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31534}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102522,"speed":24.46,"longitude":-105.0469496},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":93,"serialNumber":15522,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"00000000000003E132","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"eastbound_I80_111.16_130.84_SAT-DEE31829_RC_RSI80ERAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102522,"speed":24.46,"longitude":-105.0469496},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":92,"serialNumber":15521,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"000000000000032307","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416780373,"long":-1087800160},"name":"westbound_I80_111.16_130.84_SAT-60EFA4BA_RC_RSI80ERAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087818098,"lat":416784087}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}},{"delta":{"node-LatLon":{"lon":-1087907758,"lat":416802744}}},{"delta":{"node-LatLon":{"lon":-1087979504,"lat":416817627}}},{"delta":{"node-LatLon":{"lon":-1088052834,"lat":416835667}}},{"delta":{"node-LatLon":{"lon":-1088118809,"lat":416865925}}},{"delta":{"node-LatLon":{"lon":-1088189118,"lat":416887479}}},{"delta":{"node-LatLon":{"lon":-1088265956,"lat":416884718}}},{"delta":{"node-LatLon":{"lon":-1088342780,"lat":416881687}}},{"delta":{"node-LatLon":{"lon":-1088419492,"lat":416886484}}},{"delta":{"node-LatLon":{"lon":-1088493522,"lat":416903350}}},{"delta":{"node-LatLon":{"lon":-1088567559,"lat":416920405}}},{"delta":{"node-LatLon":{"lon":-1088642038,"lat":416936455}}},{"delta":{"node-LatLon":{"lon":-1088718787,"lat":416933306}}},{"delta":{"node-LatLon":{"lon":-1088792811,"lat":416916445}}},{"delta":{"node-LatLon":{"lon":-1088868743,"lat":416911533}}},{"delta":{"node-LatLon":{"lon":-1088944838,"lat":416921259}}},{"delta":{"node-LatLon":{"lon":-1089020933,"lat":416916370}}},{"delta":{"node-LatLon":{"lon":-1089090262,"lat":416891382}}},{"delta":{"node-LatLon":{"lon":-1089158444,"lat":416862087}}},{"delta":{"node-LatLon":{"lon":-1089206739,"lat":416816167}}},{"delta":{"node-LatLon":{"lon":-1089229701,"lat":416761043}}},{"delta":{"node-LatLon":{"lon":-1089278517,"lat":416719880}}},{"delta":{"node-LatLon":{"lon":-1089348486,"lat":416699184}}},{"delta":{"node-LatLon":{"lon":-1089425832,"lat":416694198}}},{"delta":{"node-LatLon":{"lon":-1089503649,"lat":416693457}}},{"delta":{"node-LatLon":{"lon":-1089580254,"lat":416689749}}},{"delta":{"node-LatLon":{"lon":-1089654935,"lat":416679778}}},{"delta":{"node-LatLon":{"lon":-1089727701,"lat":416664462}}},{"delta":{"node-LatLon":{"lon":-1089800350,"lat":416634151}}},{"delta":{"node-LatLon":{"lon":-1089872661,"lat":416603374}}},{"delta":{"node-LatLon":{"lon":-1089942282,"lat":416573714}}},{"delta":{"node-LatLon":{"lon":-1090009243,"lat":416545210}}},{"delta":{"node-LatLon":{"lon":-1090076173,"lat":416516668}}},{"delta":{"node-LatLon":{"lon":-1090143069,"lat":416488162}}},{"delta":{"node-LatLon":{"lon":-1090209918,"lat":416459596}}},{"delta":{"node-LatLon":{"lon":-1090277470,"lat":416430810}}},{"delta":{"node-LatLon":{"lon":-1090345662,"lat":416401720}}},{"delta":{"node-LatLon":{"lon":-1090413831,"lat":416372606}}},{"delta":{"node-LatLon":{"lon":-1090485302,"lat":416354405}}},{"delta":{"node-LatLon":{"lon":-1090559312,"lat":416342147}}},{"delta":{"node-LatLon":{"lon":-1090633109,"lat":416329839}}},{"delta":{"node-LatLon":{"lon":-1090706742,"lat":416317644}}},{"delta":{"node-LatLon":{"lon":-1090780363,"lat":416305412}}},{"delta":{"node-LatLon":{"lon":-1090854362,"lat":416289159}}},{"delta":{"node-LatLon":{"lon":-1090923703,"lat":416263510}}},{"delta":{"node-LatLon":{"lon":-1090992931,"lat":416237673}}},{"delta":{"node-LatLon":{"lon":-1091062121,"lat":416211766}}},{"delta":{"node-LatLon":{"lon":-1091131370,"lat":416185951}}},{"delta":{"node-LatLon":{"lon":-1091198118,"lat":416160999}}},{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091281511,"lat":416129751}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000011111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416780373,"long":-1087800160}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025176,"speed":24.46,"longitude":-105.0469782},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":91,"serialNumber":15520,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31497,"packetID":"0000000000000BC3EF","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415325796,"long":-1094614954},"name":"westbound_I80_90.098_90.312_SAT-8D4B0B6B_RC_GRTUNWB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094647572,"lat":415340958}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094677547,"lat":415358928}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000000100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415325796,"long":-1094614954}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31497}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025176,"speed":24.46,"longitude":-105.0469782},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":90,"serialNumber":15519,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:12.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000A6155","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415272879,"long":-1094524441},"name":"westbound_I80_83.01_91.0_SAT-BCC7F251_RC_RSI80WGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}},{"delta":{"node-LatLon":{"lon":-1094567629,"lat":415301333}}},{"delta":{"node-LatLon":{"lon":-1094598552,"lat":415318326}}},{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}},{"delta":{"node-LatLon":{"lon":-1094725523,"lat":415382855}}},{"delta":{"node-LatLon":{"lon":-1094759103,"lat":415397020}}},{"delta":{"node-LatLon":{"lon":-1094787376,"lat":415416158}}},{"delta":{"node-LatLon":{"lon":-1094803681,"lat":415442345}}},{"delta":{"node-LatLon":{"lon":-1094827523,"lat":415464696}}},{"delta":{"node-LatLon":{"lon":-1094857768,"lat":415483037}}},{"delta":{"node-LatLon":{"lon":-1094888001,"lat":415501390}}},{"delta":{"node-LatLon":{"lon":-1094919170,"lat":415518798}}},{"delta":{"node-LatLon":{"lon":-1094953846,"lat":415531903}}},{"delta":{"node-LatLon":{"lon":-1094991158,"lat":415539943}}},{"delta":{"node-LatLon":{"lon":-1095029104,"lat":415543908}}},{"delta":{"node-LatLon":{"lon":-1095067107,"lat":415547593}}},{"delta":{"node-LatLon":{"lon":-1095105120,"lat":415551220}}},{"delta":{"node-LatLon":{"lon":-1095142989,"lat":415555524}}},{"delta":{"node-LatLon":{"lon":-1095178583,"lat":415565942}}},{"delta":{"node-LatLon":{"lon":-1095212839,"lat":415581431}}},{"delta":{"node-LatLon":{"lon":-1095248825,"lat":415594355}}},{"delta":{"node-LatLon":{"lon":-1095287864,"lat":415600639}}},{"delta":{"node-LatLon":{"lon":-1095327361,"lat":415605311}}},{"delta":{"node-LatLon":{"lon":-1095366831,"lat":415610104}}},{"delta":{"node-LatLon":{"lon":-1095403172,"lat":415618111}}},{"delta":{"node-LatLon":{"lon":-1095437320,"lat":415630465}}},{"delta":{"node-LatLon":{"lon":-1095472268,"lat":415641378}}},{"delta":{"node-LatLon":{"lon":-1095509638,"lat":415645822}}},{"delta":{"node-LatLon":{"lon":-1095547341,"lat":415643461}}},{"delta":{"node-LatLon":{"lon":-1095583235,"lat":415634481}}},{"delta":{"node-LatLon":{"lon":-1095616942,"lat":415621427}}},{"delta":{"node-LatLon":{"lon":-1095650544,"lat":415608220}}},{"delta":{"node-LatLon":{"lon":-1095684389,"lat":415595379}}},{"delta":{"node-LatLon":{"lon":-1095720328,"lat":415586411}}},{"delta":{"node-LatLon":{"lon":-1095758260,"lat":415580697}}},{"delta":{"node-LatLon":{"lon":-1095796228,"lat":415575112}}},{"delta":{"node-LatLon":{"lon":-1095834193,"lat":415569520}}},{"delta":{"node-LatLon":{"lon":-1095872158,"lat":415563926}}},{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415272879,"long":-1094524441}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025133,"speed":24.46,"longitude":-105.0470067},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":89,"serialNumber":15518,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000210A5","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415546021,"long":-1095927626},"name":"eastbound_I80_83.01_91.0_SAT-AEC2BC20_RC_RSI80WGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095910196,"lat":415552425}}},{"delta":{"node-LatLon":{"lon":-1095873554,"lat":415561468}}},{"delta":{"node-LatLon":{"lon":-1095835664,"lat":415567106}}},{"delta":{"node-LatLon":{"lon":-1095797758,"lat":415572690}}},{"delta":{"node-LatLon":{"lon":-1095759854,"lat":415578281}}},{"delta":{"node-LatLon":{"lon":-1095721965,"lat":415583926}}},{"delta":{"node-LatLon":{"lon":-1095685445,"lat":415592676}}},{"delta":{"node-LatLon":{"lon":-1095651117,"lat":415605559}}},{"delta":{"node-LatLon":{"lon":-1095617101,"lat":415618922}}},{"delta":{"node-LatLon":{"lon":-1095583008,"lat":415632176}}},{"delta":{"node-LatLon":{"lon":-1095546731,"lat":415641373}}},{"delta":{"node-LatLon":{"lon":-1095509731,"lat":415643672}}},{"delta":{"node-LatLon":{"lon":-1095473059,"lat":415639326}}},{"delta":{"node-LatLon":{"lon":-1095438752,"lat":415628644}}},{"delta":{"node-LatLon":{"lon":-1095405325,"lat":415616388}}},{"delta":{"node-LatLon":{"lon":-1095369730,"lat":415608358}}},{"delta":{"node-LatLon":{"lon":-1095330616,"lat":415603528}}},{"delta":{"node-LatLon":{"lon":-1095291457,"lat":415598888}}},{"delta":{"node-LatLon":{"lon":-1095252639,"lat":415593016}}},{"delta":{"node-LatLon":{"lon":-1095216703,"lat":415580638}}},{"delta":{"node-LatLon":{"lon":-1095182775,"lat":415565235}}},{"delta":{"node-LatLon":{"lon":-1095147149,"lat":415554096}}},{"delta":{"node-LatLon":{"lon":-1095108985,"lat":415549420}}},{"delta":{"node-LatLon":{"lon":-1095070589,"lat":415545729}}},{"delta":{"node-LatLon":{"lon":-1095032188,"lat":415542064}}},{"delta":{"node-LatLon":{"lon":-1094993831,"lat":415538174}}},{"delta":{"node-LatLon":{"lon":-1094956860,"lat":415530480}}},{"delta":{"node-LatLon":{"lon":-1094922411,"lat":415517802}}},{"delta":{"node-LatLon":{"lon":-1094891469,"lat":415500743}}},{"delta":{"node-LatLon":{"lon":-1094861594,"lat":415482600}}},{"delta":{"node-LatLon":{"lon":-1094831707,"lat":415464468}}},{"delta":{"node-LatLon":{"lon":-1094806972,"lat":415442662}}},{"delta":{"node-LatLon":{"lon":-1094790913,"lat":415416378}}},{"delta":{"node-LatLon":{"lon":-1094763585,"lat":415396461}}},{"delta":{"node-LatLon":{"lon":-1094730035,"lat":415382264}}},{"delta":{"node-LatLon":{"lon":-1094697171,"lat":415367224}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}},{"delta":{"node-LatLon":{"lon":-1094603326,"lat":415317623}}},{"delta":{"node-LatLon":{"lon":-1094571921,"lat":415301218}}},{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415546021,"long":-1095927626}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025088,"speed":24.46,"longitude":-105.0470353},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":88,"serialNumber":15517,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31498,"packetID":"000000000000057CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-11EB1AFB_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31498}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025046,"speed":24.46,"longitude":-105.0470638},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":87,"serialNumber":15516,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31495,"packetID":"00000000000008F38B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416142272,"long":-1091248169},"name":"westbound_I80_104.83_111.16_SAT-F2240036_RC_RSI80MARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091298228,"lat":416123561}}},{"delta":{"node-LatLon":{"lon":-1091334018,"lat":416110189}}},{"delta":{"node-LatLon":{"lon":-1091369795,"lat":416096798}}},{"delta":{"node-LatLon":{"lon":-1091405563,"lat":416083396}}},{"delta":{"node-LatLon":{"lon":-1091441283,"lat":416069923}}},{"delta":{"node-LatLon":{"lon":-1091474700,"lat":416053537}}},{"delta":{"node-LatLon":{"lon":-1091501964,"lat":416033828}}},{"delta":{"node-LatLon":{"lon":-1091526844,"lat":416012368}}},{"delta":{"node-LatLon":{"lon":-1091552241,"lat":415991270}}},{"delta":{"node-LatLon":{"lon":-1091583184,"lat":415974991}}},{"delta":{"node-LatLon":{"lon":-1091618832,"lat":415965599}}},{"delta":{"node-LatLon":{"lon":-1091657262,"lat":415963124}}},{"delta":{"node-LatLon":{"lon":-1091695868,"lat":415962098}}},{"delta":{"node-LatLon":{"lon":-1091734473,"lat":415961055}}},{"delta":{"node-LatLon":{"lon":-1091772519,"lat":415956756}}},{"delta":{"node-LatLon":{"lon":-1091806953,"lat":415943769}}},{"delta":{"node-LatLon":{"lon":-1091836882,"lat":415930461}}},{"delta":{"node-LatLon":{"lon":-1091869287,"lat":415921267}}},{"delta":{"node-LatLon":{"lon":-1091903898,"lat":415920097}}},{"delta":{"node-LatLon":{"lon":-1091937392,"lat":415926747}}},{"delta":{"node-LatLon":{"lon":-1091966574,"lat":415940771}}},{"delta":{"node-LatLon":{"lon":-1091990723,"lat":415963402}}},{"delta":{"node-LatLon":{"lon":-1092004823,"lat":415990502}}},{"delta":{"node-LatLon":{"lon":-1092019104,"lat":416017543}}},{"delta":{"node-LatLon":{"lon":-1092043521,"lat":416040022}}},{"delta":{"node-LatLon":{"lon":-1092074899,"lat":416057166}}},{"delta":{"node-LatLon":{"lon":-1092100017,"lat":416070268}}},{"delta":{"node-LatLon":{"lon":-1092125100,"lat":416083407}}},{"delta":{"node-LatLon":{"lon":-1092151035,"lat":416095519}}},{"delta":{"node-LatLon":{"lon":-1092180024,"lat":416102624}}},{"delta":{"node-LatLon":{"lon":-1092210485,"lat":416103734}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416142272,"long":-1091248169}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31495}},"msgCnt":2}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025046,"speed":24.46,"longitude":-105.0470638},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":86,"serialNumber":15515,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31496,"packetID":"0000000000000CADD0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-F2F2EEFD_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31496}},"msgCnt":8}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1025002,"speed":24.46,"longitude":-105.0470924},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":85,"serialNumber":15514,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31490,"packetID":"0000000000000A5426","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416070648,"long":-1092309469},"name":"eastbound_I80_104.83_111.16_SAT-5D20AE10_RC_RSI80MARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092256961,"lat":416090938}}},{"delta":{"node-LatLon":{"lon":-1092220011,"lat":416100743}}},{"delta":{"node-LatLon":{"lon":-1092180837,"lat":416100613}}},{"delta":{"node-LatLon":{"lon":-1092144100,"lat":416090411}}},{"delta":{"node-LatLon":{"lon":-1092111577,"lat":416073768}}},{"delta":{"node-LatLon":{"lon":-1092079251,"lat":416056897}}},{"delta":{"node-LatLon":{"lon":-1092047614,"lat":416039914}}},{"delta":{"node-LatLon":{"lon":-1092022496,"lat":416017802}}},{"delta":{"node-LatLon":{"lon":-1092007875,"lat":415990813}}},{"delta":{"node-LatLon":{"lon":-1091994030,"lat":415963562}}},{"delta":{"node-LatLon":{"lon":-1091970384,"lat":415940547}}},{"delta":{"node-LatLon":{"lon":-1091941029,"lat":415925731}}},{"delta":{"node-LatLon":{"lon":-1091907083,"lat":415918255}}},{"delta":{"node-LatLon":{"lon":-1091871710,"lat":415918755}}},{"delta":{"node-LatLon":{"lon":-1091838259,"lat":415927373}}},{"delta":{"node-LatLon":{"lon":-1091807633,"lat":415940869}}},{"delta":{"node-LatLon":{"lon":-1091773693,"lat":415954295}}},{"delta":{"node-LatLon":{"lon":-1091735915,"lat":415958860}}},{"delta":{"node-LatLon":{"lon":-1091697507,"lat":415959950}}},{"delta":{"node-LatLon":{"lon":-1091659097,"lat":415960991}}},{"delta":{"node-LatLon":{"lon":-1091620811,"lat":415963173}}},{"delta":{"node-LatLon":{"lon":-1091584800,"lat":415972056}}},{"delta":{"node-LatLon":{"lon":-1091553176,"lat":415987749}}},{"delta":{"node-LatLon":{"lon":-1091527289,"lat":416008625}}},{"delta":{"node-LatLon":{"lon":-1091502330,"lat":416030163}}},{"delta":{"node-LatLon":{"lon":-1091474365,"lat":416049452}}},{"delta":{"node-LatLon":{"lon":-1091440655,"lat":416065279}}},{"delta":{"node-LatLon":{"lon":-1091405002,"lat":416078597}}},{"delta":{"node-LatLon":{"lon":-1091369361,"lat":416091933}}},{"delta":{"node-LatLon":{"lon":-1091333716,"lat":416105264}}},{"delta":{"node-LatLon":{"lon":-1091298057,"lat":416118575}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416070648,"long":-1092309469}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31490}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024958,"speed":24.46,"longitude":-105.0471209},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":84,"serialNumber":15513,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"000000000000073298","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411170053,"long":-1048682540},"name":"westbound_I80_348.36_358.5_SAT-C5FF6D31_RC_CHEYI80WLARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048702211,"lat":411170073}}},{"delta":{"node-LatLon":{"lon":-1048721881,"lat":411170051}}},{"delta":{"node-LatLon":{"lon":-1048761222,"lat":411169874}}},{"delta":{"node-LatLon":{"lon":-1048800563,"lat":411169714}}},{"delta":{"node-LatLon":{"lon":-1048839240,"lat":411169551}}},{"delta":{"node-LatLon":{"lon":-1048877917,"lat":411169445}}},{"delta":{"node-LatLon":{"lon":-1048916593,"lat":411169353}}},{"delta":{"node-LatLon":{"lon":-1048955270,"lat":411169236}}},{"delta":{"node-LatLon":{"lon":-1048993946,"lat":411169016}}},{"delta":{"node-LatLon":{"lon":-1049032247,"lat":411168874}}},{"delta":{"node-LatLon":{"lon":-1049070527,"lat":411168170}}},{"delta":{"node-LatLon":{"lon":-1049108247,"lat":411163290}}},{"delta":{"node-LatLon":{"lon":-1049145661,"lat":411157085}}},{"delta":{"node-LatLon":{"lon":-1049183059,"lat":411150832}}},{"delta":{"node-LatLon":{"lon":-1049220325,"lat":411144893}}},{"delta":{"node-LatLon":{"lon":-1049257999,"lat":411140682}}},{"delta":{"node-LatLon":{"lon":-1049295723,"lat":411136728}}},{"delta":{"node-LatLon":{"lon":-1049333444,"lat":411132751}}},{"delta":{"node-LatLon":{"lon":-1049371183,"lat":411128874}}},{"delta":{"node-LatLon":{"lon":-1049409390,"lat":411124909}}},{"delta":{"node-LatLon":{"lon":-1049447598,"lat":411120949}}},{"delta":{"node-LatLon":{"lon":-1049485797,"lat":411116940}}},{"delta":{"node-LatLon":{"lon":-1049524006,"lat":411112988}}},{"delta":{"node-LatLon":{"lon":-1049562308,"lat":411109647}}},{"delta":{"node-LatLon":{"lon":-1049600401,"lat":411107207}}},{"delta":{"node-LatLon":{"lon":-1049638492,"lat":411104750}}},{"delta":{"node-LatLon":{"lon":-1049676581,"lat":411102282}}},{"delta":{"node-LatLon":{"lon":-1049714466,"lat":411098457}}},{"delta":{"node-LatLon":{"lon":-1049752216,"lat":411093893}}},{"delta":{"node-LatLon":{"lon":-1049790068,"lat":411089292}}},{"delta":{"node-LatLon":{"lon":-1049827923,"lat":411084707}}},{"delta":{"node-LatLon":{"lon":-1049865779,"lat":411080125}}},{"delta":{"node-LatLon":{"lon":-1049903602,"lat":411075397}}},{"delta":{"node-LatLon":{"lon":-1049940392,"lat":411067384}}},{"delta":{"node-LatLon":{"lon":-1049976102,"lat":411057362}}},{"delta":{"node-LatLon":{"lon":-1050011796,"lat":411047308}}},{"delta":{"node-LatLon":{"lon":-1050047479,"lat":411037232}}},{"delta":{"node-LatLon":{"lon":-1050083173,"lat":411027181}}},{"delta":{"node-LatLon":{"lon":-1050119263,"lat":411018037}}},{"delta":{"node-LatLon":{"lon":-1050156120,"lat":411013697}}},{"delta":{"node-LatLon":{"lon":-1050193406,"lat":411014492}}},{"delta":{"node-LatLon":{"lon":-1050230066,"lat":411019821}}},{"delta":{"node-LatLon":{"lon":-1050266545,"lat":411025893}}},{"delta":{"node-LatLon":{"lon":-1050303026,"lat":411031959}}},{"delta":{"node-LatLon":{"lon":-1050341801,"lat":411036364}}},{"delta":{"node-LatLon":{"lon":-1050381045,"lat":411036216}}},{"delta":{"node-LatLon":{"lon":-1050420282,"lat":411035204}}},{"delta":{"node-LatLon":{"lon":-1050459188,"lat":411031556}}},{"delta":{"node-LatLon":{"lon":-1050497693,"lat":411025753}}},{"delta":{"node-LatLon":{"lon":-1050534808,"lat":411020098}}},{"delta":{"node-LatLon":{"lon":-1050571919,"lat":411014428}}},{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050627605,"lat":411006003}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411170053,"long":-1048682540}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024958,"speed":24.46,"longitude":-105.0471209},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":83,"serialNumber":15512,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"0000000000000B9403","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":410998545,"long":-1050648246},"name":"eastbound_I80_348.36_358.5_SAT-D8707F73_RC_CHEYI80WLARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050629421,"lat":411001016}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}},{"delta":{"node-LatLon":{"lon":-1050573199,"lat":411009532}}},{"delta":{"node-LatLon":{"lon":-1050535715,"lat":411015202}}},{"delta":{"node-LatLon":{"lon":-1050498229,"lat":411020862}}},{"delta":{"node-LatLon":{"lon":-1050460327,"lat":411026546}}},{"delta":{"node-LatLon":{"lon":-1050422091,"lat":411030485}}},{"delta":{"node-LatLon":{"lon":-1050383473,"lat":411031428}}},{"delta":{"node-LatLon":{"lon":-1050344848,"lat":411031826}}},{"delta":{"node-LatLon":{"lon":-1050306653,"lat":411027659}}},{"delta":{"node-LatLon":{"lon":-1050269678,"lat":411021507}}},{"delta":{"node-LatLon":{"lon":-1050232676,"lat":411015448}}},{"delta":{"node-LatLon":{"lon":-1050195535,"lat":411009957}}},{"delta":{"node-LatLon":{"lon":-1050157751,"lat":411008904}}},{"delta":{"node-LatLon":{"lon":-1050120335,"lat":411013008}}},{"delta":{"node-LatLon":{"lon":-1050084082,"lat":411021875}}},{"delta":{"node-LatLon":{"lon":-1050048325,"lat":411031899}}},{"delta":{"node-LatLon":{"lon":-1050012604,"lat":411041995}}},{"delta":{"node-LatLon":{"lon":-1049976865,"lat":411052057}}},{"delta":{"node-LatLon":{"lon":-1049941141,"lat":411062151}}},{"delta":{"node-LatLon":{"lon":-1049904488,"lat":411070470}}},{"delta":{"node-LatLon":{"lon":-1049866692,"lat":411075206}}},{"delta":{"node-LatLon":{"lon":-1049828870,"lat":411079830}}},{"delta":{"node-LatLon":{"lon":-1049791039,"lat":411084415}}},{"delta":{"node-LatLon":{"lon":-1049753209,"lat":411089002}}},{"delta":{"node-LatLon":{"lon":-1049715382,"lat":411093589}}},{"delta":{"node-LatLon":{"lon":-1049677431,"lat":411097499}}},{"delta":{"node-LatLon":{"lon":-1049639263,"lat":411099987}}},{"delta":{"node-LatLon":{"lon":-1049601097,"lat":411102498}}},{"delta":{"node-LatLon":{"lon":-1049562935,"lat":411105044}}},{"delta":{"node-LatLon":{"lon":-1049524970,"lat":411108146}}},{"delta":{"node-LatLon":{"lon":-1049487125,"lat":411112044}}},{"delta":{"node-LatLon":{"lon":-1049449291,"lat":411116003}}},{"delta":{"node-LatLon":{"lon":-1049411457,"lat":411119968}}},{"delta":{"node-LatLon":{"lon":-1049373623,"lat":411123930}}},{"delta":{"node-LatLon":{"lon":-1049335535,"lat":411127975}}},{"delta":{"node-LatLon":{"lon":-1049297422,"lat":411131886}}},{"delta":{"node-LatLon":{"lon":-1049259309,"lat":411135796}}},{"delta":{"node-LatLon":{"lon":-1049221247,"lat":411139978}}},{"delta":{"node-LatLon":{"lon":-1049183591,"lat":411145899}}},{"delta":{"node-LatLon":{"lon":-1049146455,"lat":411152154}}},{"delta":{"node-LatLon":{"lon":-1049109301,"lat":411158352}}},{"delta":{"node-LatLon":{"lon":-1049071864,"lat":411163355}}},{"delta":{"node-LatLon":{"lon":-1049033848,"lat":411164138}}},{"delta":{"node-LatLon":{"lon":-1048995803,"lat":411164285}}},{"delta":{"node-LatLon":{"lon":-1048957165,"lat":411164452}}},{"delta":{"node-LatLon":{"lon":-1048918528,"lat":411164604}}},{"delta":{"node-LatLon":{"lon":-1048879891,"lat":411164841}}},{"delta":{"node-LatLon":{"lon":-1048841254,"lat":411165037}}},{"delta":{"node-LatLon":{"lon":-1048802617,"lat":411165193}}},{"delta":{"node-LatLon":{"lon":-1048763807,"lat":411165332}}},{"delta":{"node-LatLon":{"lon":-1048724997,"lat":411165480}}},{"delta":{"node-LatLon":{"lon":-1048705592,"lat":411165575}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":410998545,"long":-1050648246}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024915,"speed":24.46,"longitude":-105.0471495},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":82,"serialNumber":15511,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"000000000000087964","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411011592,"long":-1050590473},"name":"westbound_I80_335.11_348.36_SAT-4982596C_RC_CHEYI80WHARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050684029,"lat":411002155}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411011592,"long":-1050590473}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024871,"speed":24.46,"longitude":-105.047178},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":81,"serialNumber":15510,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31281,"packetID":"0000000000000A3B4E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-6CD34EF8_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31281}},"msgCnt":6}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024871,"speed":24.46,"longitude":-105.047178},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":80,"serialNumber":15509,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31276,"packetID":"0000000000000C7BDC","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411583071,"long":-1045194573},"name":"westbound_I80_370.1_377.35_SAT-1F3353B9_RC_CHEYI80EPBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1045213731,"lat":411583474}}},{"delta":{"node-LatLon":{"lon":-1045252048,"lat":411584277}}},{"delta":{"node-LatLon":{"lon":-1045290377,"lat":411584588}}},{"delta":{"node-LatLon":{"lon":-1045329055,"lat":411584606}}},{"delta":{"node-LatLon":{"lon":-1045367733,"lat":411584612}}},{"delta":{"node-LatLon":{"lon":-1045406412,"lat":411584626}}},{"delta":{"node-LatLon":{"lon":-1045445090,"lat":411584615}}},{"delta":{"node-LatLon":{"lon":-1045483768,"lat":411584618}}},{"delta":{"node-LatLon":{"lon":-1045521914,"lat":411584627}}},{"delta":{"node-LatLon":{"lon":-1045560059,"lat":411584625}}},{"delta":{"node-LatLon":{"lon":-1045598205,"lat":411584639}}},{"delta":{"node-LatLon":{"lon":-1045636350,"lat":411584589}}},{"delta":{"node-LatLon":{"lon":-1045674495,"lat":411584576}}},{"delta":{"node-LatLon":{"lon":-1045712807,"lat":411584579}}},{"delta":{"node-LatLon":{"lon":-1045751120,"lat":411584598}}},{"delta":{"node-LatLon":{"lon":-1045789432,"lat":411584756}}},{"delta":{"node-LatLon":{"lon":-1045827743,"lat":411584908}}},{"delta":{"node-LatLon":{"lon":-1045866056,"lat":411585030}}},{"delta":{"node-LatLon":{"lon":-1045904386,"lat":411585214}}},{"delta":{"node-LatLon":{"lon":-1045942717,"lat":411585361}}},{"delta":{"node-LatLon":{"lon":-1045981047,"lat":411585545}}},{"delta":{"node-LatLon":{"lon":-1046019378,"lat":411585693}}},{"delta":{"node-LatLon":{"lon":-1046057708,"lat":411585870}}},{"delta":{"node-LatLon":{"lon":-1046096147,"lat":411586011}}},{"delta":{"node-LatLon":{"lon":-1046134585,"lat":411586177}}},{"delta":{"node-LatLon":{"lon":-1046173023,"lat":411586326}}},{"delta":{"node-LatLon":{"lon":-1046211460,"lat":411586584}}},{"delta":{"node-LatLon":{"lon":-1046249897,"lat":411586868}}},{"delta":{"node-LatLon":{"lon":-1046288331,"lat":411587218}}},{"delta":{"node-LatLon":{"lon":-1046326766,"lat":411587517}}},{"delta":{"node-LatLon":{"lon":-1046365200,"lat":411587809}}},{"delta":{"node-LatLon":{"lon":-1046403636,"lat":411588036}}},{"delta":{"node-LatLon":{"lon":-1046442034,"lat":411586845}}},{"delta":{"node-LatLon":{"lon":-1046479971,"lat":411583989}}},{"delta":{"node-LatLon":{"lon":-1046517601,"lat":411579361}}},{"delta":{"node-LatLon":{"lon":-1046554803,"lat":411573054}}},{"delta":{"node-LatLon":{"lon":-1046591419,"lat":411565023}}},{"delta":{"node-LatLon":{"lon":-1046609462,"lat":411560366}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411583071,"long":-1045194573}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31276}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024828,"speed":24.46,"longitude":-105.0472065},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":79,"serialNumber":15508,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31276,"packetID":"00000000000005CEB8","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411550674,"long":-1046626808},"name":"eastbound_I80_370.1_377.35_SAT-D4C24D15_RC_CHEYI80EPBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1046609118,"lat":411555717}}},{"delta":{"node-LatLon":{"lon":-1046591249,"lat":411560386}}},{"delta":{"node-LatLon":{"lon":-1046554972,"lat":411568439}}},{"delta":{"node-LatLon":{"lon":-1046518106,"lat":411574777}}},{"delta":{"node-LatLon":{"lon":-1046480798,"lat":411579409}}},{"delta":{"node-LatLon":{"lon":-1046443186,"lat":411582321}}},{"delta":{"node-LatLon":{"lon":-1046405109,"lat":411583506}}},{"delta":{"node-LatLon":{"lon":-1046366997,"lat":411583305}}},{"delta":{"node-LatLon":{"lon":-1046328885,"lat":411583053}}},{"delta":{"node-LatLon":{"lon":-1046290773,"lat":411582732}}},{"delta":{"node-LatLon":{"lon":-1046252662,"lat":411582431}}},{"delta":{"node-LatLon":{"lon":-1046213997,"lat":411582141}}},{"delta":{"node-LatLon":{"lon":-1046175333,"lat":411581845}}},{"delta":{"node-LatLon":{"lon":-1046136667,"lat":411581682}}},{"delta":{"node-LatLon":{"lon":-1046098002,"lat":411581519}}},{"delta":{"node-LatLon":{"lon":-1046059336,"lat":411581347}}},{"delta":{"node-LatLon":{"lon":-1046021098,"lat":411581225}}},{"delta":{"node-LatLon":{"lon":-1045982860,"lat":411581049}}},{"delta":{"node-LatLon":{"lon":-1045944622,"lat":411580911}}},{"delta":{"node-LatLon":{"lon":-1045906384,"lat":411580755}}},{"delta":{"node-LatLon":{"lon":-1045868146,"lat":411580589}}},{"delta":{"node-LatLon":{"lon":-1045829878,"lat":411580440}}},{"delta":{"node-LatLon":{"lon":-1045791610,"lat":411580257}}},{"delta":{"node-LatLon":{"lon":-1045753341,"lat":411580119}}},{"delta":{"node-LatLon":{"lon":-1045715072,"lat":411580125}}},{"delta":{"node-LatLon":{"lon":-1045676803,"lat":411580094}}},{"delta":{"node-LatLon":{"lon":-1045638356,"lat":411580096}}},{"delta":{"node-LatLon":{"lon":-1045599910,"lat":411580126}}},{"delta":{"node-LatLon":{"lon":-1045561463,"lat":411580111}}},{"delta":{"node-LatLon":{"lon":-1045523016,"lat":411580105}}},{"delta":{"node-LatLon":{"lon":-1045484569,"lat":411580102}}},{"delta":{"node-LatLon":{"lon":-1045446114,"lat":411580096}}},{"delta":{"node-LatLon":{"lon":-1045407659,"lat":411580116}}},{"delta":{"node-LatLon":{"lon":-1045369203,"lat":411580107}}},{"delta":{"node-LatLon":{"lon":-1045330748,"lat":411580102}}},{"delta":{"node-LatLon":{"lon":-1045292292,"lat":411580094}}},{"delta":{"node-LatLon":{"lon":-1045253937,"lat":411579790}}},{"delta":{"node-LatLon":{"lon":-1045215592,"lat":411579032}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411550674,"long":-1046626808}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":770}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31276}},"msgCnt":4}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024828,"speed":24.46,"longitude":-105.0472065},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":78,"serialNumber":15507,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31484,"packetID":"0000000000000687E2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411011592,"long":-1050590473},"name":"westbound_I80_335.11_348.36_SAT-592E2A83_RC_CHEYI80WHARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050609033,"lat":411008772}}},{"delta":{"node-LatLon":{"lon":-1050684029,"lat":411002155}}},{"delta":{"node-LatLon":{"lon":-1050760755,"lat":411002869}}},{"delta":{"node-LatLon":{"lon":-1050837364,"lat":411000370}}},{"delta":{"node-LatLon":{"lon":-1050914524,"lat":410995536}}},{"delta":{"node-LatLon":{"lon":-1050990956,"lat":410984444}}},{"delta":{"node-LatLon":{"lon":-1051067254,"lat":410973454}}},{"delta":{"node-LatLon":{"lon":-1051144365,"lat":410982302}}},{"delta":{"node-LatLon":{"lon":-1051221934,"lat":410988766}}},{"delta":{"node-LatLon":{"lon":-1051297925,"lat":410988342}}},{"delta":{"node-LatLon":{"lon":-1051371832,"lat":410988032}}},{"delta":{"node-LatLon":{"lon":-1051445141,"lat":410995292}}},{"delta":{"node-LatLon":{"lon":-1051521267,"lat":411000337}}},{"delta":{"node-LatLon":{"lon":-1051596119,"lat":410988652}}},{"delta":{"node-LatLon":{"lon":-1051671284,"lat":410977720}}},{"delta":{"node-LatLon":{"lon":-1051747551,"lat":410971360}}},{"delta":{"node-LatLon":{"lon":-1051823993,"lat":410966522}}},{"delta":{"node-LatLon":{"lon":-1051899770,"lat":410963108}}},{"delta":{"node-LatLon":{"lon":-1051974706,"lat":410954064}}},{"delta":{"node-LatLon":{"lon":-1052048783,"lat":410962474}}},{"delta":{"node-LatLon":{"lon":-1052113110,"lat":410992814}}},{"delta":{"node-LatLon":{"lon":-1052178141,"lat":411022378}}},{"delta":{"node-LatLon":{"lon":-1052248856,"lat":411045103}}},{"delta":{"node-LatLon":{"lon":-1052325706,"lat":411048940}}},{"delta":{"node-LatLon":{"lon":-1052402452,"lat":411049814}}},{"delta":{"node-LatLon":{"lon":-1052476819,"lat":411061846}}},{"delta":{"node-LatLon":{"lon":-1052547987,"lat":411082724}}},{"delta":{"node-LatLon":{"lon":-1052619267,"lat":411103644}}},{"delta":{"node-LatLon":{"lon":-1052690521,"lat":411124618}}},{"delta":{"node-LatLon":{"lon":-1052758326,"lat":411153468}}},{"delta":{"node-LatLon":{"lon":-1052824352,"lat":411187145}}},{"delta":{"node-LatLon":{"lon":-1052891232,"lat":411219785}}},{"delta":{"node-LatLon":{"lon":-1052963092,"lat":411239437}}},{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053057596,"lat":411251395}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411011592,"long":-1050590473}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31484}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024784,"speed":24.46,"longitude":-105.0472351},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":76,"serialNumber":15505,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31483,"packetID":"0000000000000B4F4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411246688,"long":-1053019776},"name":"westbound_I80_323.05_335.11_SAT-B91A2E52_RC_LARI80ECHEYBD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053038685,"lat":411249047}}},{"delta":{"node-LatLon":{"lon":-1053114552,"lat":411256735}}},{"delta":{"node-LatLon":{"lon":-1053190756,"lat":411261912}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054127454,"lat":411694572}}},{"delta":{"node-LatLon":{"lon":-1054164403,"lat":411745737}}},{"delta":{"node-LatLon":{"lon":-1054200041,"lat":411796105}}},{"delta":{"node-LatLon":{"lon":-1054218886,"lat":411851211}}},{"delta":{"node-LatLon":{"lon":-1054243815,"lat":411905185}}},{"delta":{"node-LatLon":{"lon":-1054287780,"lat":411952905}}},{"delta":{"node-LatLon":{"lon":-1054331852,"lat":412000578}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000001111}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411246688,"long":-1053019776}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":4868}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31483}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024784,"speed":24.46,"longitude":-105.0472351},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":77,"serialNumber":15506,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31484,"packetID":"00000000000004AA70","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-9AFEBCD7_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31484}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024741,"speed":24.46,"longitude":-105.0472635},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":75,"serialNumber":15504,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31483,"packetID":"0000000000000F25D6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412420501,"long":-1054392109},"name":"eastbound_I80_323.05_335.11_SAT-2FAB6C57_RC_LARI80ECHEYBI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054375725,"lat":412379414}}},{"delta":{"node-LatLon":{"lon":-1054372327,"lat":412322445}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111110000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412420501,"long":-1054392109}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":4868}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31483}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024697,"speed":24.46,"longitude":-105.0472922},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":74,"serialNumber":15503,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:11.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000992DB","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412969911,"long":-1055922054},"name":"westbound_I80_290.44_313.19_SAT-39E13EDB_RC_LARI80WQDHLD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055939598,"lat":412974628}}},{"delta":{"node-LatLon":{"lon":-1056011013,"lat":412993846}}},{"delta":{"node-LatLon":{"lon":-1056083564,"lat":413013351}}},{"delta":{"node-LatLon":{"lon":-1056136131,"lat":413051965}}},{"delta":{"node-LatLon":{"lon":-1056142604,"lat":413111070}}},{"delta":{"node-LatLon":{"lon":-1056147739,"lat":413170299}}},{"delta":{"node-LatLon":{"lon":-1056152707,"lat":413227440}}},{"delta":{"node-LatLon":{"lon":-1056157480,"lat":413282495}}},{"delta":{"node-LatLon":{"lon":-1056162332,"lat":413337546}}},{"delta":{"node-LatLon":{"lon":-1056179338,"lat":413394642}}},{"delta":{"node-LatLon":{"lon":-1056241841,"lat":413429971}}},{"delta":{"node-LatLon":{"lon":-1056308986,"lat":413460456}}},{"delta":{"node-LatLon":{"lon":-1056375806,"lat":413490715}}},{"delta":{"node-LatLon":{"lon":-1056448549,"lat":413509883}}},{"delta":{"node-LatLon":{"lon":-1056524673,"lat":413510070}}},{"delta":{"node-LatLon":{"lon":-1056600806,"lat":413509928}}},{"delta":{"node-LatLon":{"lon":-1056677878,"lat":413509777}}},{"delta":{"node-LatLon":{"lon":-1056755890,"lat":413509624}}},{"delta":{"node-LatLon":{"lon":-1056833901,"lat":413509486}}},{"delta":{"node-LatLon":{"lon":-1056911534,"lat":413509321}}},{"delta":{"node-LatLon":{"lon":-1056988345,"lat":413503756}}},{"delta":{"node-LatLon":{"lon":-1057063632,"lat":413496157}}},{"delta":{"node-LatLon":{"lon":-1057138866,"lat":413506949}}},{"delta":{"node-LatLon":{"lon":-1057214104,"lat":413517735}}},{"delta":{"node-LatLon":{"lon":-1057289680,"lat":413528551}}},{"delta":{"node-LatLon":{"lon":-1057365257,"lat":413539367}}},{"delta":{"node-LatLon":{"lon":-1057440379,"lat":413550309}}},{"delta":{"node-LatLon":{"lon":-1057512568,"lat":413568354}}},{"delta":{"node-LatLon":{"lon":-1057584309,"lat":413587502}}},{"delta":{"node-LatLon":{"lon":-1057657989,"lat":413607176}}},{"delta":{"node-LatLon":{"lon":-1057731667,"lat":413626859}}},{"delta":{"node-LatLon":{"lon":-1057799444,"lat":413654138}}},{"delta":{"node-LatLon":{"lon":-1057862738,"lat":413685955}}},{"delta":{"node-LatLon":{"lon":-1057926032,"lat":413717776}}},{"delta":{"node-LatLon":{"lon":-1057990466,"lat":413750126}}},{"delta":{"node-LatLon":{"lon":-1058054871,"lat":413782512}}},{"delta":{"node-LatLon":{"lon":-1058117509,"lat":413815643}}},{"delta":{"node-LatLon":{"lon":-1058164753,"lat":413859952}}},{"delta":{"node-LatLon":{"lon":-1058205339,"lat":413908152}}},{"delta":{"node-LatLon":{"lon":-1058246686,"lat":413957163}}},{"delta":{"node-LatLon":{"lon":-1058288005,"lat":414006188}}},{"delta":{"node-LatLon":{"lon":-1058329488,"lat":414055451}}},{"delta":{"node-LatLon":{"lon":-1058376904,"lat":414101638}}},{"delta":{"node-LatLon":{"lon":-1058441692,"lat":414133752}}},{"delta":{"node-LatLon":{"lon":-1058509642,"lat":414161765}}},{"delta":{"node-LatLon":{"lon":-1058577606,"lat":414189762}}},{"delta":{"node-LatLon":{"lon":-1058645229,"lat":414217630}}},{"delta":{"node-LatLon":{"lon":-1058712523,"lat":414245352}}},{"delta":{"node-LatLon":{"lon":-1058779847,"lat":414273037}}},{"delta":{"node-LatLon":{"lon":-1058847466,"lat":414300930}}},{"delta":{"node-LatLon":{"lon":-1058915586,"lat":414328088}}},{"delta":{"node-LatLon":{"lon":-1058989523,"lat":414342520}}},{"delta":{"node-LatLon":{"lon":-1059064093,"lat":414353551}}},{"delta":{"node-LatLon":{"lon":-1059138674,"lat":414364546}}},{"delta":{"node-LatLon":{"lon":-1059214026,"lat":414375694}}},{"delta":{"node-LatLon":{"lon":-1059289381,"lat":414386834}}},{"delta":{"node-LatLon":{"lon":-1059363802,"lat":414397824}}},{"delta":{"node-LatLon":{"lon":-1059437301,"lat":414408619}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412969911,"long":-1055922054}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024697,"speed":24.46,"longitude":-105.0472922},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":73,"serialNumber":15502,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000A5948","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-864EB729_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024653,"speed":24.46,"longitude":-105.0473207},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":72,"serialNumber":15501,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"0000000000000F8642","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414403179,"long":-1059400563},"name":"westbound_I80_279.86_290.44_SAT-D62DB515_RC_LARI80WRAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059418929,"lat":414405912}}},{"delta":{"node-LatLon":{"lon":-1059437301,"lat":414408619}}},{"delta":{"node-LatLon":{"lon":-1059474045,"lat":414414043}}},{"delta":{"node-LatLon":{"lon":-1059510782,"lat":414419489}}},{"delta":{"node-LatLon":{"lon":-1059549177,"lat":414426609}}},{"delta":{"node-LatLon":{"lon":-1059587159,"lat":414434951}}},{"delta":{"node-LatLon":{"lon":-1059624866,"lat":414443931}}},{"delta":{"node-LatLon":{"lon":-1059658797,"lat":414459046}}},{"delta":{"node-LatLon":{"lon":-1059685629,"lat":414480816}}},{"delta":{"node-LatLon":{"lon":-1059708612,"lat":414504233}}},{"delta":{"node-LatLon":{"lon":-1059731631,"lat":414527631}}},{"delta":{"node-LatLon":{"lon":-1059754662,"lat":414551022}}},{"delta":{"node-LatLon":{"lon":-1059777663,"lat":414574431}}},{"delta":{"node-LatLon":{"lon":-1059800605,"lat":414597873}}},{"delta":{"node-LatLon":{"lon":-1059825019,"lat":414620504}}},{"delta":{"node-LatLon":{"lon":-1059854975,"lat":414638959}}},{"delta":{"node-LatLon":{"lon":-1059886652,"lat":414655790}}},{"delta":{"node-LatLon":{"lon":-1059918347,"lat":414672602}}},{"delta":{"node-LatLon":{"lon":-1059950027,"lat":414689430}}},{"delta":{"node-LatLon":{"lon":-1059981533,"lat":414706207}}},{"delta":{"node-LatLon":{"lon":-1060013094,"lat":414722925}}},{"delta":{"node-LatLon":{"lon":-1060044644,"lat":414739656}}},{"delta":{"node-LatLon":{"lon":-1060076151,"lat":414756434}}},{"delta":{"node-LatLon":{"lon":-1060107672,"lat":414773199}}},{"delta":{"node-LatLon":{"lon":-1060138668,"lat":414789614}}},{"delta":{"node-LatLon":{"lon":-1060169596,"lat":414806103}}},{"delta":{"node-LatLon":{"lon":-1060200600,"lat":414822512}}},{"delta":{"node-LatLon":{"lon":-1060231565,"lat":414838964}}},{"delta":{"node-LatLon":{"lon":-1060262552,"lat":414855394}}},{"delta":{"node-LatLon":{"lon":-1060294303,"lat":414872314}}},{"delta":{"node-LatLon":{"lon":-1060326101,"lat":414889184}}},{"delta":{"node-LatLon":{"lon":-1060357880,"lat":414906076}}},{"delta":{"node-LatLon":{"lon":-1060389415,"lat":414923223}}},{"delta":{"node-LatLon":{"lon":-1060420573,"lat":414940760}}},{"delta":{"node-LatLon":{"lon":-1060450509,"lat":414958838}}},{"delta":{"node-LatLon":{"lon":-1060475868,"lat":414980491}}},{"delta":{"node-LatLon":{"lon":-1060495507,"lat":415005280}}},{"delta":{"node-LatLon":{"lon":-1060510699,"lat":415031818}}},{"delta":{"node-LatLon":{"lon":-1060524843,"lat":415058673}}},{"delta":{"node-LatLon":{"lon":-1060533417,"lat":415086879}}},{"delta":{"node-LatLon":{"lon":-1060540264,"lat":415115378}}},{"delta":{"node-LatLon":{"lon":-1060547197,"lat":415143865}}},{"delta":{"node-LatLon":{"lon":-1060554077,"lat":415172359}}},{"delta":{"node-LatLon":{"lon":-1060561492,"lat":415200772}}},{"delta":{"node-LatLon":{"lon":-1060576552,"lat":415227429}}},{"delta":{"node-LatLon":{"lon":-1060600749,"lat":415249961}}},{"delta":{"node-LatLon":{"lon":-1060632200,"lat":415266697}}},{"delta":{"node-LatLon":{"lon":-1060666183,"lat":415280527}}},{"delta":{"node-LatLon":{"lon":-1060695463,"lat":415299353}}},{"delta":{"node-LatLon":{"lon":-1060719162,"lat":415322019}}},{"delta":{"node-LatLon":{"lon":-1060742498,"lat":415344904}}},{"delta":{"node-LatLon":{"lon":-1060765869,"lat":415367768}}},{"delta":{"node-LatLon":{"lon":-1060789259,"lat":415390622}}},{"delta":{"node-LatLon":{"lon":-1060812632,"lat":415413487}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414403179,"long":-1059400563}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":38}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.102461,"speed":24.46,"longitude":-105.0473492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":70,"serialNumber":15499,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31288,"packetID":"00000000000007A7DE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417284807,"long":-1077291383},"name":"westbound_I80_173.41_187.2_SAT-2205BAF6_RC_WAMI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1077310157,"lat":417280493}}},{"delta":{"node-LatLon":{"lon":-1077365582,"lat":417267865}}},{"delta":{"node-LatLon":{"lon":-1077438858,"lat":417251174}}},{"delta":{"node-LatLon":{"lon":-1077512126,"lat":417234471}}},{"delta":{"node-LatLon":{"lon":-1077586147,"lat":417217588}}},{"delta":{"node-LatLon":{"lon":-1077660175,"lat":417200729}}},{"delta":{"node-LatLon":{"lon":-1077734162,"lat":417183833}}},{"delta":{"node-LatLon":{"lon":-1077808136,"lat":417166974}}},{"delta":{"node-LatLon":{"lon":-1077882091,"lat":417150070}}},{"delta":{"node-LatLon":{"lon":-1077955526,"lat":417133360}}},{"delta":{"node-LatLon":{"lon":-1078028926,"lat":417116571}}},{"delta":{"node-LatLon":{"lon":-1078102836,"lat":417099694}}},{"delta":{"node-LatLon":{"lon":-1078177231,"lat":417082670}}},{"delta":{"node-LatLon":{"lon":-1078251628,"lat":417065655}}},{"delta":{"node-LatLon":{"lon":-1078327521,"lat":417053313}}},{"delta":{"node-LatLon":{"lon":-1078405145,"lat":417051623}}},{"delta":{"node-LatLon":{"lon":-1078479666,"lat":417055725}}},{"delta":{"node-LatLon":{"lon":-1078551136,"lat":417059767}}},{"delta":{"node-LatLon":{"lon":-1078622626,"lat":417063607}}},{"delta":{"node-LatLon":{"lon":-1078700426,"lat":417063986}}},{"delta":{"node-LatLon":{"lon":-1078778089,"lat":417060211}}},{"delta":{"node-LatLon":{"lon":-1078855705,"lat":417056048}}},{"delta":{"node-LatLon":{"lon":-1078933113,"lat":417050466}}},{"delta":{"node-LatLon":{"lon":-1079008244,"lat":417035644}}},{"delta":{"node-LatLon":{"lon":-1079081128,"lat":417014156}}},{"delta":{"node-LatLon":{"lon":-1079153926,"lat":416992506}}},{"delta":{"node-LatLon":{"lon":-1079226268,"lat":416970973}}},{"delta":{"node-LatLon":{"lon":-1079298175,"lat":416949594}}},{"delta":{"node-LatLon":{"lon":-1079370073,"lat":416928204}}},{"delta":{"node-LatLon":{"lon":-1079442362,"lat":416906685}}},{"delta":{"node-LatLon":{"lon":-1079513134,"lat":416882726}}},{"delta":{"node-LatLon":{"lon":-1079579019,"lat":416852706}}},{"delta":{"node-LatLon":{"lon":-1079644289,"lat":416822906}}},{"delta":{"node-LatLon":{"lon":-1079709585,"lat":416793141}}},{"delta":{"node-LatLon":{"lon":-1079776048,"lat":416762809}}},{"delta":{"node-LatLon":{"lon":-1079809278,"lat":416747641}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417284807,"long":-1077291383}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31288}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024653,"speed":24.46,"longitude":-105.0473207},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":71,"serialNumber":15500,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.999Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31500,"packetID":"00000000000002CC1B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415446372,"long":-1060853758},"name":"eastbound_I80_279.86_290.44_SAT-D603EB78_RC_LARI80WRAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060818850,"lat":415412221}}},{"delta":{"node-LatLon":{"lon":-1060795306,"lat":415389123}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}},{"delta":{"node-LatLon":{"lon":-1060748924,"lat":415342529}}},{"delta":{"node-LatLon":{"lon":-1060725901,"lat":415319138}}},{"delta":{"node-LatLon":{"lon":-1060702891,"lat":415295740}}},{"delta":{"node-LatLon":{"lon":-1060677392,"lat":415274709}}},{"delta":{"node-LatLon":{"lon":-1060645465,"lat":415259440}}},{"delta":{"node-LatLon":{"lon":-1060611694,"lat":415246452}}},{"delta":{"node-LatLon":{"lon":-1060583936,"lat":415227230}}},{"delta":{"node-LatLon":{"lon":-1060567112,"lat":415201829}}},{"delta":{"node-LatLon":{"lon":-1060559250,"lat":415173268}}},{"delta":{"node-LatLon":{"lon":-1060551848,"lat":415144627}}},{"delta":{"node-LatLon":{"lon":-1060544578,"lat":415115967}}},{"delta":{"node-LatLon":{"lon":-1060537212,"lat":415087321}}},{"delta":{"node-LatLon":{"lon":-1060528192,"lat":415058965}}},{"delta":{"node-LatLon":{"lon":-1060513843,"lat":415031898}}},{"delta":{"node-LatLon":{"lon":-1060498684,"lat":415005075}}},{"delta":{"node-LatLon":{"lon":-1060479584,"lat":414979768}}},{"delta":{"node-LatLon":{"lon":-1060454612,"lat":414957536}}},{"delta":{"node-LatLon":{"lon":-1060424994,"lat":414938765}}},{"delta":{"node-LatLon":{"lon":-1060394265,"lat":414920704}}},{"delta":{"node-LatLon":{"lon":-1060362947,"lat":414903230}}},{"delta":{"node-LatLon":{"lon":-1060331139,"lat":414886261}}},{"delta":{"node-LatLon":{"lon":-1060299282,"lat":414869343}}},{"delta":{"node-LatLon":{"lon":-1060267401,"lat":414852453}}},{"delta":{"node-LatLon":{"lon":-1060236377,"lat":414836034}}},{"delta":{"node-LatLon":{"lon":-1060205413,"lat":414819550}}},{"delta":{"node-LatLon":{"lon":-1060174405,"lat":414803116}}},{"delta":{"node-LatLon":{"lon":-1060143426,"lat":414786651}}},{"delta":{"node-LatLon":{"lon":-1060112442,"lat":414770191}}},{"delta":{"node-LatLon":{"lon":-1060080853,"lat":414753421}}},{"delta":{"node-LatLon":{"lon":-1060049273,"lat":414736640}}},{"delta":{"node-LatLon":{"lon":-1060017699,"lat":414719856}}},{"delta":{"node-LatLon":{"lon":-1059986118,"lat":414703079}}},{"delta":{"node-LatLon":{"lon":-1059954550,"lat":414686289}}},{"delta":{"node-LatLon":{"lon":-1059923262,"lat":414669701}}},{"delta":{"node-LatLon":{"lon":-1059892003,"lat":414653083}}},{"delta":{"node-LatLon":{"lon":-1059860748,"lat":414636462}}},{"delta":{"node-LatLon":{"lon":-1059830894,"lat":414618511}}},{"delta":{"node-LatLon":{"lon":-1059806580,"lat":414596316}}},{"delta":{"node-LatLon":{"lon":-1059783729,"lat":414573041}}},{"delta":{"node-LatLon":{"lon":-1059760839,"lat":414549787}}},{"delta":{"node-LatLon":{"lon":-1059737946,"lat":414526535}}},{"delta":{"node-LatLon":{"lon":-1059715065,"lat":414503278}}},{"delta":{"node-LatLon":{"lon":-1059692206,"lat":414480008}}},{"delta":{"node-LatLon":{"lon":-1059665100,"lat":414457204}}},{"delta":{"node-LatLon":{"lon":-1059630733,"lat":414440918}}},{"delta":{"node-LatLon":{"lon":-1059592047,"lat":414431361}}},{"delta":{"node-LatLon":{"lon":-1059552953,"lat":414422717}}},{"delta":{"node-LatLon":{"lon":-1059513468,"lat":414415217}}},{"delta":{"node-LatLon":{"lon":-1059476558,"lat":414409805}}},{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059421200,"lat":414401666}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415446372,"long":-1060853758}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31500}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024565,"speed":24.46,"longitude":-105.0473778},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":69,"serialNumber":15498,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000D0886","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416734737,"long":-1079825644},"name":"eastbound_I80_173.41_187.2_SAT-045A0F96_RC_WAMI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1079808962,"lat":416742355}}},{"delta":{"node-LatLon":{"lon":-1079775625,"lat":416757626}}},{"delta":{"node-LatLon":{"lon":-1079708864,"lat":416788062}}},{"delta":{"node-LatLon":{"lon":-1079643761,"lat":416817816}}},{"delta":{"node-LatLon":{"lon":-1079578633,"lat":416847544}}},{"delta":{"node-LatLon":{"lon":-1079513021,"lat":416877502}}},{"delta":{"node-LatLon":{"lon":-1079442840,"lat":416901685}}},{"delta":{"node-LatLon":{"lon":-1079370904,"lat":416923092}}},{"delta":{"node-LatLon":{"lon":-1079299318,"lat":416944401}}},{"delta":{"node-LatLon":{"lon":-1079227728,"lat":416965705}}},{"delta":{"node-LatLon":{"lon":-1079155246,"lat":416987264}}},{"delta":{"node-LatLon":{"lon":-1079081869,"lat":417009073}}},{"delta":{"node-LatLon":{"lon":-1079008281,"lat":417030466}}},{"delta":{"node-LatLon":{"lon":-1078933736,"lat":417045037}}},{"delta":{"node-LatLon":{"lon":-1078857144,"lat":417051301}}},{"delta":{"node-LatLon":{"lon":-1078779954,"lat":417053823}}},{"delta":{"node-LatLon":{"lon":-1078702612,"lat":417056324}}},{"delta":{"node-LatLon":{"lon":-1078625459,"lat":417053640}}},{"delta":{"node-LatLon":{"lon":-1078550508,"lat":417040669}}},{"delta":{"node-LatLon":{"lon":-1078475631,"lat":417027451}}},{"delta":{"node-LatLon":{"lon":-1078399078,"lat":417028105}}},{"delta":{"node-LatLon":{"lon":-1078325093,"lat":417044119}}},{"delta":{"node-LatLon":{"lon":-1078251401,"lat":417060961}}},{"delta":{"node-LatLon":{"lon":-1078177495,"lat":417077861}}},{"delta":{"node-LatLon":{"lon":-1078103576,"lat":417094732}}},{"delta":{"node-LatLon":{"lon":-1078029860,"lat":417111623}}},{"delta":{"node-LatLon":{"lon":-1077956308,"lat":417128437}}},{"delta":{"node-LatLon":{"lon":-1077882736,"lat":417145206}}},{"delta":{"node-LatLon":{"lon":-1077809037,"lat":417162072}}},{"delta":{"node-LatLon":{"lon":-1077735310,"lat":417178873}}},{"delta":{"node-LatLon":{"lon":-1077661395,"lat":417195740}}},{"delta":{"node-LatLon":{"lon":-1077587285,"lat":417212656}}},{"delta":{"node-LatLon":{"lon":-1077513154,"lat":417229528}}},{"delta":{"node-LatLon":{"lon":-1077440112,"lat":417246166}}},{"delta":{"node-LatLon":{"lon":-1077367083,"lat":417262839}}},{"delta":{"node-LatLon":{"lon":-1077292868,"lat":417279720}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416734737,"long":-1079825644}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024565,"speed":24.46,"longitude":-105.0473778},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":68,"serialNumber":15497,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"00000000000004E35A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415325796,"long":-1094614954},"name":"westbound_I80_90.098_90.312_SAT-5302F9D3_RC_GRTUNWB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094647572,"lat":415340958}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094677547,"lat":415358928}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000000100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415325796,"long":-1094614954}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024523,"speed":24.46,"longitude":-105.0474064},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":67,"serialNumber":15496,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000064D1D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415367224,"long":-1094697171},"name":"eastbound_I80_90.109_90.324_SAT-D48C7646_RC_GRTUNEB","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094682069,"lat":415358380}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094651565,"lat":415340982}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000010000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415367224,"long":-1094697171}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024523,"speed":24.46,"longitude":-105.0474064},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":66,"serialNumber":15495,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000A389B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416780373,"long":-1087800160},"name":"westbound_I80_111.16_130.84_SAT-69F3DB7B_RC_RSI80ERAWD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087818098,"lat":416784087}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}},{"delta":{"node-LatLon":{"lon":-1087907758,"lat":416802744}}},{"delta":{"node-LatLon":{"lon":-1087979504,"lat":416817627}}},{"delta":{"node-LatLon":{"lon":-1088052834,"lat":416835667}}},{"delta":{"node-LatLon":{"lon":-1088118809,"lat":416865925}}},{"delta":{"node-LatLon":{"lon":-1088189118,"lat":416887479}}},{"delta":{"node-LatLon":{"lon":-1088265956,"lat":416884718}}},{"delta":{"node-LatLon":{"lon":-1088342780,"lat":416881687}}},{"delta":{"node-LatLon":{"lon":-1088419492,"lat":416886484}}},{"delta":{"node-LatLon":{"lon":-1088493522,"lat":416903350}}},{"delta":{"node-LatLon":{"lon":-1088567559,"lat":416920405}}},{"delta":{"node-LatLon":{"lon":-1088642038,"lat":416936455}}},{"delta":{"node-LatLon":{"lon":-1088718787,"lat":416933306}}},{"delta":{"node-LatLon":{"lon":-1088792811,"lat":416916445}}},{"delta":{"node-LatLon":{"lon":-1088868743,"lat":416911533}}},{"delta":{"node-LatLon":{"lon":-1088944838,"lat":416921259}}},{"delta":{"node-LatLon":{"lon":-1089020933,"lat":416916370}}},{"delta":{"node-LatLon":{"lon":-1089090262,"lat":416891382}}},{"delta":{"node-LatLon":{"lon":-1089158444,"lat":416862087}}},{"delta":{"node-LatLon":{"lon":-1089206739,"lat":416816167}}},{"delta":{"node-LatLon":{"lon":-1089229701,"lat":416761043}}},{"delta":{"node-LatLon":{"lon":-1089278517,"lat":416719880}}},{"delta":{"node-LatLon":{"lon":-1089348486,"lat":416699184}}},{"delta":{"node-LatLon":{"lon":-1089425832,"lat":416694198}}},{"delta":{"node-LatLon":{"lon":-1089503649,"lat":416693457}}},{"delta":{"node-LatLon":{"lon":-1089580254,"lat":416689749}}},{"delta":{"node-LatLon":{"lon":-1089654935,"lat":416679778}}},{"delta":{"node-LatLon":{"lon":-1089727701,"lat":416664462}}},{"delta":{"node-LatLon":{"lon":-1089800350,"lat":416634151}}},{"delta":{"node-LatLon":{"lon":-1089872661,"lat":416603374}}},{"delta":{"node-LatLon":{"lon":-1089942282,"lat":416573714}}},{"delta":{"node-LatLon":{"lon":-1090009243,"lat":416545210}}},{"delta":{"node-LatLon":{"lon":-1090076173,"lat":416516668}}},{"delta":{"node-LatLon":{"lon":-1090143069,"lat":416488162}}},{"delta":{"node-LatLon":{"lon":-1090209918,"lat":416459596}}},{"delta":{"node-LatLon":{"lon":-1090277470,"lat":416430810}}},{"delta":{"node-LatLon":{"lon":-1090345662,"lat":416401720}}},{"delta":{"node-LatLon":{"lon":-1090413831,"lat":416372606}}},{"delta":{"node-LatLon":{"lon":-1090485302,"lat":416354405}}},{"delta":{"node-LatLon":{"lon":-1090559312,"lat":416342147}}},{"delta":{"node-LatLon":{"lon":-1090633109,"lat":416329839}}},{"delta":{"node-LatLon":{"lon":-1090706742,"lat":416317644}}},{"delta":{"node-LatLon":{"lon":-1090780363,"lat":416305412}}},{"delta":{"node-LatLon":{"lon":-1090854362,"lat":416289159}}},{"delta":{"node-LatLon":{"lon":-1090923703,"lat":416263510}}},{"delta":{"node-LatLon":{"lon":-1090992931,"lat":416237673}}},{"delta":{"node-LatLon":{"lon":-1091062121,"lat":416211766}}},{"delta":{"node-LatLon":{"lon":-1091131370,"lat":416185951}}},{"delta":{"node-LatLon":{"lon":-1091198118,"lat":416160999}}},{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091281511,"lat":416129751}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000011111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416780373,"long":-1087800160}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024479,"speed":24.46,"longitude":-105.0474349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":65,"serialNumber":15494,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000002E727","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416118575,"long":-1091298057},"name":"eastbound_I80_111.16_130.84_SAT-E83FBA7D_RC_RSI80ERAWI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091281363,"lat":416124819}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}},{"delta":{"node-LatLon":{"lon":-1091197851,"lat":416155972}}},{"delta":{"node-LatLon":{"lon":-1091131081,"lat":416180959}}},{"delta":{"node-LatLon":{"lon":-1091061948,"lat":416206791}}},{"delta":{"node-LatLon":{"lon":-1090992816,"lat":416232629}}},{"delta":{"node-LatLon":{"lon":-1090923774,"lat":416258380}}},{"delta":{"node-LatLon":{"lon":-1090854860,"lat":416284101}}},{"delta":{"node-LatLon":{"lon":-1090781365,"lat":416300658}}},{"delta":{"node-LatLon":{"lon":-1090707741,"lat":416312858}}},{"delta":{"node-LatLon":{"lon":-1090634136,"lat":416325123}}},{"delta":{"node-LatLon":{"lon":-1090559994,"lat":416337414}}},{"delta":{"node-LatLon":{"lon":-1090485346,"lat":416349841}}},{"delta":{"node-LatLon":{"lon":-1090413083,"lat":416367890}}},{"delta":{"node-LatLon":{"lon":-1090344728,"lat":416396917}}},{"delta":{"node-LatLon":{"lon":-1090276443,"lat":416426043}}},{"delta":{"node-LatLon":{"lon":-1090208858,"lat":416454891}}},{"delta":{"node-LatLon":{"lon":-1090141947,"lat":416483428}}},{"delta":{"node-LatLon":{"lon":-1090075022,"lat":416511951}}},{"delta":{"node-LatLon":{"lon":-1090008142,"lat":416540450}}},{"delta":{"node-LatLon":{"lon":-1089941256,"lat":416568945}}},{"delta":{"node-LatLon":{"lon":-1089871816,"lat":416598516}}},{"delta":{"node-LatLon":{"lon":-1089799835,"lat":416629182}}},{"delta":{"node-LatLon":{"lon":-1089727632,"lat":416659547}}},{"delta":{"node-LatLon":{"lon":-1089655858,"lat":416675127}}},{"delta":{"node-LatLon":{"lon":-1089582024,"lat":416685077}}},{"delta":{"node-LatLon":{"lon":-1089506421,"lat":416691287}}},{"delta":{"node-LatLon":{"lon":-1089429140,"lat":416692075}}},{"delta":{"node-LatLon":{"lon":-1089352223,"lat":416696411}}},{"delta":{"node-LatLon":{"lon":-1089279710,"lat":416716970}}},{"delta":{"node-LatLon":{"lon":-1089227822,"lat":416758449}}},{"delta":{"node-LatLon":{"lon":-1089204951,"lat":416814026}}},{"delta":{"node-LatLon":{"lon":-1089158069,"lat":416859587}}},{"delta":{"node-LatLon":{"lon":-1089091158,"lat":416888588}}},{"delta":{"node-LatLon":{"lon":-1089022414,"lat":416913801}}},{"delta":{"node-LatLon":{"lon":-1088946848,"lat":416919297}}},{"delta":{"node-LatLon":{"lon":-1088870915,"lat":416909691}}},{"delta":{"node-LatLon":{"lon":-1088794827,"lat":416913757}}},{"delta":{"node-LatLon":{"lon":-1088720754,"lat":416930631}}},{"delta":{"node-LatLon":{"lon":-1088644702,"lat":416934650}}},{"delta":{"node-LatLon":{"lon":-1088570748,"lat":416918931}}},{"delta":{"node-LatLon":{"lon":-1088496778,"lat":416901918}}},{"delta":{"node-LatLon":{"lon":-1088422329,"lat":416884944}}},{"delta":{"node-LatLon":{"lon":-1088345218,"lat":416879835}}},{"delta":{"node-LatLon":{"lon":-1088268750,"lat":416882872}}},{"delta":{"node-LatLon":{"lon":-1088192271,"lat":416885698}}},{"delta":{"node-LatLon":{"lon":-1088121685,"lat":416865247}}},{"delta":{"node-LatLon":{"lon":-1088055642,"lat":416834746}}},{"delta":{"node-LatLon":{"lon":-1087982459,"lat":416815998}}},{"delta":{"node-LatLon":{"lon":-1087910924,"lat":416801153}}},{"delta":{"node-LatLon":{"lon":-1087839399,"lat":416786287}}},{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111110000000000}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416118575,"long":-1091298057}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024479,"speed":24.46,"longitude":-105.0474349},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":64,"serialNumber":15493,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"0000000000000EF239","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415272879,"long":-1094524441},"name":"westbound_I80_83.01_91.0_SAT-AE5C67DC_RC_RSI80WGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}},{"delta":{"node-LatLon":{"lon":-1094567629,"lat":415301333}}},{"delta":{"node-LatLon":{"lon":-1094598552,"lat":415318326}}},{"delta":{"node-LatLon":{"lon":-1094631379,"lat":415333237}}},{"delta":{"node-LatLon":{"lon":-1094662661,"lat":415349838}}},{"delta":{"node-LatLon":{"lon":-1094692747,"lat":415367707}}},{"delta":{"node-LatLon":{"lon":-1094725523,"lat":415382855}}},{"delta":{"node-LatLon":{"lon":-1094759103,"lat":415397020}}},{"delta":{"node-LatLon":{"lon":-1094787376,"lat":415416158}}},{"delta":{"node-LatLon":{"lon":-1094803681,"lat":415442345}}},{"delta":{"node-LatLon":{"lon":-1094827523,"lat":415464696}}},{"delta":{"node-LatLon":{"lon":-1094857768,"lat":415483037}}},{"delta":{"node-LatLon":{"lon":-1094888001,"lat":415501390}}},{"delta":{"node-LatLon":{"lon":-1094919170,"lat":415518798}}},{"delta":{"node-LatLon":{"lon":-1094953846,"lat":415531903}}},{"delta":{"node-LatLon":{"lon":-1094991158,"lat":415539943}}},{"delta":{"node-LatLon":{"lon":-1095029104,"lat":415543908}}},{"delta":{"node-LatLon":{"lon":-1095067107,"lat":415547593}}},{"delta":{"node-LatLon":{"lon":-1095105120,"lat":415551220}}},{"delta":{"node-LatLon":{"lon":-1095142989,"lat":415555524}}},{"delta":{"node-LatLon":{"lon":-1095178583,"lat":415565942}}},{"delta":{"node-LatLon":{"lon":-1095212839,"lat":415581431}}},{"delta":{"node-LatLon":{"lon":-1095248825,"lat":415594355}}},{"delta":{"node-LatLon":{"lon":-1095287864,"lat":415600639}}},{"delta":{"node-LatLon":{"lon":-1095327361,"lat":415605311}}},{"delta":{"node-LatLon":{"lon":-1095366831,"lat":415610104}}},{"delta":{"node-LatLon":{"lon":-1095403172,"lat":415618111}}},{"delta":{"node-LatLon":{"lon":-1095437320,"lat":415630465}}},{"delta":{"node-LatLon":{"lon":-1095472268,"lat":415641378}}},{"delta":{"node-LatLon":{"lon":-1095509638,"lat":415645822}}},{"delta":{"node-LatLon":{"lon":-1095547341,"lat":415643461}}},{"delta":{"node-LatLon":{"lon":-1095583235,"lat":415634481}}},{"delta":{"node-LatLon":{"lon":-1095616942,"lat":415621427}}},{"delta":{"node-LatLon":{"lon":-1095650544,"lat":415608220}}},{"delta":{"node-LatLon":{"lon":-1095684389,"lat":415595379}}},{"delta":{"node-LatLon":{"lon":-1095720328,"lat":415586411}}},{"delta":{"node-LatLon":{"lon":-1095758260,"lat":415580697}}},{"delta":{"node-LatLon":{"lon":-1095796228,"lat":415575112}}},{"delta":{"node-LatLon":{"lon":-1095834193,"lat":415569520}}},{"delta":{"node-LatLon":{"lon":-1095872158,"lat":415563926}}},{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415272879,"long":-1094524441}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024436,"speed":24.46,"longitude":-105.0474634},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":63,"serialNumber":15492,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000004FE29","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415546021,"long":-1095927626},"name":"eastbound_I80_83.01_91.0_SAT-51917CF8_RC_RSI80WGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095910196,"lat":415552425}}},{"delta":{"node-LatLon":{"lon":-1095873554,"lat":415561468}}},{"delta":{"node-LatLon":{"lon":-1095835664,"lat":415567106}}},{"delta":{"node-LatLon":{"lon":-1095797758,"lat":415572690}}},{"delta":{"node-LatLon":{"lon":-1095759854,"lat":415578281}}},{"delta":{"node-LatLon":{"lon":-1095721965,"lat":415583926}}},{"delta":{"node-LatLon":{"lon":-1095685445,"lat":415592676}}},{"delta":{"node-LatLon":{"lon":-1095651117,"lat":415605559}}},{"delta":{"node-LatLon":{"lon":-1095617101,"lat":415618922}}},{"delta":{"node-LatLon":{"lon":-1095583008,"lat":415632176}}},{"delta":{"node-LatLon":{"lon":-1095546731,"lat":415641373}}},{"delta":{"node-LatLon":{"lon":-1095509731,"lat":415643672}}},{"delta":{"node-LatLon":{"lon":-1095473059,"lat":415639326}}},{"delta":{"node-LatLon":{"lon":-1095438752,"lat":415628644}}},{"delta":{"node-LatLon":{"lon":-1095405325,"lat":415616388}}},{"delta":{"node-LatLon":{"lon":-1095369730,"lat":415608358}}},{"delta":{"node-LatLon":{"lon":-1095330616,"lat":415603528}}},{"delta":{"node-LatLon":{"lon":-1095291457,"lat":415598888}}},{"delta":{"node-LatLon":{"lon":-1095252639,"lat":415593016}}},{"delta":{"node-LatLon":{"lon":-1095216703,"lat":415580638}}},{"delta":{"node-LatLon":{"lon":-1095182775,"lat":415565235}}},{"delta":{"node-LatLon":{"lon":-1095147149,"lat":415554096}}},{"delta":{"node-LatLon":{"lon":-1095108985,"lat":415549420}}},{"delta":{"node-LatLon":{"lon":-1095070589,"lat":415545729}}},{"delta":{"node-LatLon":{"lon":-1095032188,"lat":415542064}}},{"delta":{"node-LatLon":{"lon":-1094993831,"lat":415538174}}},{"delta":{"node-LatLon":{"lon":-1094956860,"lat":415530480}}},{"delta":{"node-LatLon":{"lon":-1094922411,"lat":415517802}}},{"delta":{"node-LatLon":{"lon":-1094891469,"lat":415500743}}},{"delta":{"node-LatLon":{"lon":-1094861594,"lat":415482600}}},{"delta":{"node-LatLon":{"lon":-1094831707,"lat":415464468}}},{"delta":{"node-LatLon":{"lon":-1094806972,"lat":415442662}}},{"delta":{"node-LatLon":{"lon":-1094790913,"lat":415416378}}},{"delta":{"node-LatLon":{"lon":-1094763585,"lat":415396461}}},{"delta":{"node-LatLon":{"lon":-1094730035,"lat":415382264}}},{"delta":{"node-LatLon":{"lon":-1094697171,"lat":415367224}}},{"delta":{"node-LatLon":{"lon":-1094666854,"lat":415349644}}},{"delta":{"node-LatLon":{"lon":-1094636062,"lat":415332555}}},{"delta":{"node-LatLon":{"lon":-1094603326,"lat":415317623}}},{"delta":{"node-LatLon":{"lon":-1094571921,"lat":415301218}}},{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415546021,"long":-1095927626}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024392,"speed":24.46,"longitude":-105.047492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":62,"serialNumber":15491,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000059505","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416103734,"long":-1092210485},"name":"westbound_I80_91.0_104.83_SAT-16CC040B_RC_RSI80WGRFGD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092225602,"lat":416102051}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}},{"delta":{"node-LatLon":{"lon":-1092295103,"lat":416078549}}},{"delta":{"node-LatLon":{"lon":-1092353802,"lat":416055730}}},{"delta":{"node-LatLon":{"lon":-1092409233,"lat":415994268}}},{"delta":{"node-LatLon":{"lon":-1092453299,"lat":415926333}}},{"delta":{"node-LatLon":{"lon":-1092494255,"lat":415863151}}},{"delta":{"node-LatLon":{"lon":-1092542043,"lat":415808289}}},{"delta":{"node-LatLon":{"lon":-1092614541,"lat":415771804}}},{"delta":{"node-LatLon":{"lon":-1092686893,"lat":415745034}}},{"delta":{"node-LatLon":{"lon":-1092755235,"lat":415719687}}},{"delta":{"node-LatLon":{"lon":-1092824046,"lat":415694227}}},{"delta":{"node-LatLon":{"lon":-1092892916,"lat":415668054}}},{"delta":{"node-LatLon":{"lon":-1092959628,"lat":415638882}}},{"delta":{"node-LatLon":{"lon":-1093026230,"lat":415609696}}},{"delta":{"node-LatLon":{"lon":-1093092855,"lat":415580545}}},{"delta":{"node-LatLon":{"lon":-1093159414,"lat":415551340}}},{"delta":{"node-LatLon":{"lon":-1093225990,"lat":415522190}}},{"delta":{"node-LatLon":{"lon":-1093292630,"lat":415493128}}},{"delta":{"node-LatLon":{"lon":-1093362756,"lat":415469236}}},{"delta":{"node-LatLon":{"lon":-1093433593,"lat":415446486}}},{"delta":{"node-LatLon":{"lon":-1093501983,"lat":415419517}}},{"delta":{"node-LatLon":{"lon":-1093570430,"lat":415392320}}},{"delta":{"node-LatLon":{"lon":-1093638825,"lat":415365052}}},{"delta":{"node-LatLon":{"lon":-1093706625,"lat":415338051}}},{"delta":{"node-LatLon":{"lon":-1093779378,"lat":415323162}}},{"delta":{"node-LatLon":{"lon":-1093855135,"lat":415332204}}},{"delta":{"node-LatLon":{"lon":-1093927477,"lat":415317094}}},{"delta":{"node-LatLon":{"lon":-1093995757,"lat":415291937}}},{"delta":{"node-LatLon":{"lon":-1094070772,"lat":415279115}}},{"delta":{"node-LatLon":{"lon":-1094147255,"lat":415276886}}},{"delta":{"node-LatLon":{"lon":-1094224449,"lat":415282426}}},{"delta":{"node-LatLon":{"lon":-1094301394,"lat":415276124}}},{"delta":{"node-LatLon":{"lon":-1094371013,"lat":415249502}}},{"delta":{"node-LatLon":{"lon":-1094443930,"lat":415236997}}},{"delta":{"node-LatLon":{"lon":-1094510066,"lat":415263454}}},{"delta":{"node-LatLon":{"lon":-1094538788,"lat":415282328}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416103734,"long":-1092210485}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.5875,"latitude":41.1024392,"speed":24.46,"longitude":-105.047492},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":61,"serialNumber":15490,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000081102","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415291783,"long":-1094557465},"name":"eastbound_I80_91.0_104.83_SAT-6E2075B5_RC_RSI80WGRFGI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1094543062,"lat":415282303}}},{"delta":{"node-LatLon":{"lon":-1094513887,"lat":415263122}}},{"delta":{"node-LatLon":{"lon":-1094447291,"lat":415235238}}},{"delta":{"node-LatLon":{"lon":-1094372833,"lat":415246383}}},{"delta":{"node-LatLon":{"lon":-1094303758,"lat":415272043}}},{"delta":{"node-LatLon":{"lon":-1094227621,"lat":415277316}}},{"delta":{"node-LatLon":{"lon":-1094148912,"lat":415268934}}},{"delta":{"node-LatLon":{"lon":-1094067595,"lat":415271090}}},{"delta":{"node-LatLon":{"lon":-1093987494,"lat":415283663}}},{"delta":{"node-LatLon":{"lon":-1093925069,"lat":415311063}}},{"delta":{"node-LatLon":{"lon":-1093857979,"lat":415329441}}},{"delta":{"node-LatLon":{"lon":-1093783441,"lat":415321335}}},{"delta":{"node-LatLon":{"lon":-1093709018,"lat":415334717}}},{"delta":{"node-LatLon":{"lon":-1093640120,"lat":415362181}}},{"delta":{"node-LatLon":{"lon":-1093571698,"lat":415389400}}},{"delta":{"node-LatLon":{"lon":-1093503273,"lat":415416618}}},{"delta":{"node-LatLon":{"lon":-1093434965,"lat":415443640}}},{"delta":{"node-LatLon":{"lon":-1093364275,"lat":415466496}}},{"delta":{"node-LatLon":{"lon":-1093294066,"lat":415490133}}},{"delta":{"node-LatLon":{"lon":-1093227263,"lat":415519148}}},{"delta":{"node-LatLon":{"lon":-1093160626,"lat":415548385}}},{"delta":{"node-LatLon":{"lon":-1093093946,"lat":415577570}}},{"delta":{"node-LatLon":{"lon":-1093027278,"lat":415606775}}},{"delta":{"node-LatLon":{"lon":-1092960606,"lat":415635979}}},{"delta":{"node-LatLon":{"lon":-1092894081,"lat":415665067}}},{"delta":{"node-LatLon":{"lon":-1092825492,"lat":415691296}}},{"delta":{"node-LatLon":{"lon":-1092756640,"lat":415716802}}},{"delta":{"node-LatLon":{"lon":-1092687981,"lat":415742243}}},{"delta":{"node-LatLon":{"lon":-1092622869,"lat":415766320}}},{"delta":{"node-LatLon":{"lon":-1092557117,"lat":415795122}}},{"delta":{"node-LatLon":{"lon":-1092507779,"lat":415838460}}},{"delta":{"node-LatLon":{"lon":-1092473834,"lat":415889802}}},{"delta":{"node-LatLon":{"lon":-1092438357,"lat":415944761}}},{"delta":{"node-LatLon":{"lon":-1092402488,"lat":415999793}}},{"delta":{"node-LatLon":{"lon":-1092361225,"lat":416049415}}},{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092274460,"lat":416084170}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415291783,"long":-1094557465}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.55,"latitude":41.1024304,"speed":24.32,"longitude":-105.047549},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":60,"serialNumber":15489,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"000000000000104155","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416142272,"long":-1091248169},"name":"westbound_I80_104.83_111.16_SAT-E4C7F6F3_RC_RSI80MARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1091264852,"lat":416136031}}},{"delta":{"node-LatLon":{"lon":-1091298228,"lat":416123561}}},{"delta":{"node-LatLon":{"lon":-1091334018,"lat":416110189}}},{"delta":{"node-LatLon":{"lon":-1091369795,"lat":416096798}}},{"delta":{"node-LatLon":{"lon":-1091405563,"lat":416083396}}},{"delta":{"node-LatLon":{"lon":-1091441283,"lat":416069923}}},{"delta":{"node-LatLon":{"lon":-1091474700,"lat":416053537}}},{"delta":{"node-LatLon":{"lon":-1091501964,"lat":416033828}}},{"delta":{"node-LatLon":{"lon":-1091526844,"lat":416012368}}},{"delta":{"node-LatLon":{"lon":-1091552241,"lat":415991270}}},{"delta":{"node-LatLon":{"lon":-1091583184,"lat":415974991}}},{"delta":{"node-LatLon":{"lon":-1091618832,"lat":415965599}}},{"delta":{"node-LatLon":{"lon":-1091657262,"lat":415963124}}},{"delta":{"node-LatLon":{"lon":-1091695868,"lat":415962098}}},{"delta":{"node-LatLon":{"lon":-1091734473,"lat":415961055}}},{"delta":{"node-LatLon":{"lon":-1091772519,"lat":415956756}}},{"delta":{"node-LatLon":{"lon":-1091806953,"lat":415943769}}},{"delta":{"node-LatLon":{"lon":-1091836882,"lat":415930461}}},{"delta":{"node-LatLon":{"lon":-1091869287,"lat":415921267}}},{"delta":{"node-LatLon":{"lon":-1091903898,"lat":415920097}}},{"delta":{"node-LatLon":{"lon":-1091937392,"lat":415926747}}},{"delta":{"node-LatLon":{"lon":-1091966574,"lat":415940771}}},{"delta":{"node-LatLon":{"lon":-1091990723,"lat":415963402}}},{"delta":{"node-LatLon":{"lon":-1092004823,"lat":415990502}}},{"delta":{"node-LatLon":{"lon":-1092019104,"lat":416017543}}},{"delta":{"node-LatLon":{"lon":-1092043521,"lat":416040022}}},{"delta":{"node-LatLon":{"lon":-1092074899,"lat":416057166}}},{"delta":{"node-LatLon":{"lon":-1092100017,"lat":416070268}}},{"delta":{"node-LatLon":{"lon":-1092125100,"lat":416083407}}},{"delta":{"node-LatLon":{"lon":-1092151035,"lat":416095519}}},{"delta":{"node-LatLon":{"lon":-1092180024,"lat":416102624}}},{"delta":{"node-LatLon":{"lon":-1092210485,"lat":416103734}}},{"delta":{"node-LatLon":{"lon":-1092240287,"lat":416098876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416142272,"long":-1091248169}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":18}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.55,"latitude":41.1024304,"speed":24.32,"longitude":-105.047549},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":59,"serialNumber":15488,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31326,"packetID":"0000000000000B625E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416070648,"long":-1092309469},"name":"eastbound_I80_104.83_111.16_SAT-7802A0B6_RC_RSI80MARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1092291967,"lat":416077413}}},{"delta":{"node-LatLon":{"lon":-1092256961,"lat":416090938}}},{"delta":{"node-LatLon":{"lon":-1092220011,"lat":416100743}}},{"delta":{"node-LatLon":{"lon":-1092180837,"lat":416100613}}},{"delta":{"node-LatLon":{"lon":-1092144100,"lat":416090411}}},{"delta":{"node-LatLon":{"lon":-1092111577,"lat":416073768}}},{"delta":{"node-LatLon":{"lon":-1092079251,"lat":416056897}}},{"delta":{"node-LatLon":{"lon":-1092047614,"lat":416039914}}},{"delta":{"node-LatLon":{"lon":-1092022496,"lat":416017802}}},{"delta":{"node-LatLon":{"lon":-1092007875,"lat":415990813}}},{"delta":{"node-LatLon":{"lon":-1091994030,"lat":415963562}}},{"delta":{"node-LatLon":{"lon":-1091970384,"lat":415940547}}},{"delta":{"node-LatLon":{"lon":-1091941029,"lat":415925731}}},{"delta":{"node-LatLon":{"lon":-1091907083,"lat":415918255}}},{"delta":{"node-LatLon":{"lon":-1091871710,"lat":415918755}}},{"delta":{"node-LatLon":{"lon":-1091838259,"lat":415927373}}},{"delta":{"node-LatLon":{"lon":-1091807633,"lat":415940869}}},{"delta":{"node-LatLon":{"lon":-1091773693,"lat":415954295}}},{"delta":{"node-LatLon":{"lon":-1091735915,"lat":415958860}}},{"delta":{"node-LatLon":{"lon":-1091697507,"lat":415959950}}},{"delta":{"node-LatLon":{"lon":-1091659097,"lat":415960991}}},{"delta":{"node-LatLon":{"lon":-1091620811,"lat":415963173}}},{"delta":{"node-LatLon":{"lon":-1091584800,"lat":415972056}}},{"delta":{"node-LatLon":{"lon":-1091553176,"lat":415987749}}},{"delta":{"node-LatLon":{"lon":-1091527289,"lat":416008625}}},{"delta":{"node-LatLon":{"lon":-1091502330,"lat":416030163}}},{"delta":{"node-LatLon":{"lon":-1091474365,"lat":416049452}}},{"delta":{"node-LatLon":{"lon":-1091440655,"lat":416065279}}},{"delta":{"node-LatLon":{"lon":-1091405002,"lat":416078597}}},{"delta":{"node-LatLon":{"lon":-1091369361,"lat":416091933}}},{"delta":{"node-LatLon":{"lon":-1091333716,"lat":416105264}}},{"delta":{"node-LatLon":{"lon":-1091298057,"lat":416118575}}},{"delta":{"node-LatLon":{"lon":-1091264664,"lat":416131054}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416070648,"long":-1092309469}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31326}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024261,"speed":24.14,"longitude":-105.0475775},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":58,"serialNumber":15487,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31551,"packetID":"000000000000038ED9","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416344087,"long":-1082586926},"name":"westbound_I80_142.17_158.55_SAT-BC3CEF3B_RC_PDI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082605867,"lat":416341147}}},{"delta":{"node-LatLon":{"lon":-1082643762,"lat":416335317}}},{"delta":{"node-LatLon":{"lon":-1082719537,"lat":416323607}}},{"delta":{"node-LatLon":{"lon":-1082795332,"lat":416311823}}},{"delta":{"node-LatLon":{"lon":-1082871219,"lat":416300396}}},{"delta":{"node-LatLon":{"lon":-1082948412,"lat":416300333}}},{"delta":{"node-LatLon":{"lon":-1083025592,"lat":416303069}}},{"delta":{"node-LatLon":{"lon":-1083102774,"lat":416305783}}},{"delta":{"node-LatLon":{"lon":-1083179715,"lat":416308441}}},{"delta":{"node-LatLon":{"lon":-1083256650,"lat":416311187}}},{"delta":{"node-LatLon":{"lon":-1083333670,"lat":416313866}}},{"delta":{"node-LatLon":{"lon":-1083410768,"lat":416316579}}},{"delta":{"node-LatLon":{"lon":-1083487872,"lat":416319193}}},{"delta":{"node-LatLon":{"lon":-1083564905,"lat":416322423}}},{"delta":{"node-LatLon":{"lon":-1083641683,"lat":416328142}}},{"delta":{"node-LatLon":{"lon":-1083718587,"lat":416332876}}},{"delta":{"node-LatLon":{"lon":-1083795496,"lat":416337572}}},{"delta":{"node-LatLon":{"lon":-1083872405,"lat":416342269}}},{"delta":{"node-LatLon":{"lon":-1083949300,"lat":416347096}}},{"delta":{"node-LatLon":{"lon":-1084026064,"lat":416352984}}},{"delta":{"node-LatLon":{"lon":-1084103063,"lat":416357400}}},{"delta":{"node-LatLon":{"lon":-1084180198,"lat":416361177}}},{"delta":{"node-LatLon":{"lon":-1084257244,"lat":416365879}}},{"delta":{"node-LatLon":{"lon":-1084326673,"lat":416370105}}},{"delta":{"node-LatLon":{"lon":-1084396100,"lat":416374353}}},{"delta":{"node-LatLon":{"lon":-1084469893,"lat":416378867}}},{"delta":{"node-LatLon":{"lon":-1084548056,"lat":416383611}}},{"delta":{"node-LatLon":{"lon":-1084626220,"lat":416388347}}},{"delta":{"node-LatLon":{"lon":-1084703702,"lat":416393060}}},{"delta":{"node-LatLon":{"lon":-1084781188,"lat":416397734}}},{"delta":{"node-LatLon":{"lon":-1084859010,"lat":416402450}}},{"delta":{"node-LatLon":{"lon":-1084937168,"lat":416407197}}},{"delta":{"node-LatLon":{"lon":-1085015328,"lat":416411930}}},{"delta":{"node-LatLon":{"lon":-1085093024,"lat":416416612}}},{"delta":{"node-LatLon":{"lon":-1085170718,"lat":416421321}}},{"delta":{"node-LatLon":{"lon":-1085248418,"lat":416425954}}},{"delta":{"node-LatLon":{"lon":-1085326100,"lat":416430747}}},{"delta":{"node-LatLon":{"lon":-1085403806,"lat":416435322}}},{"delta":{"node-LatLon":{"lon":-1085482142,"lat":416440051}}},{"delta":{"node-LatLon":{"lon":-1085560481,"lat":416444752}}},{"delta":{"node-LatLon":{"lon":-1085638702,"lat":416449395}}},{"delta":{"node-LatLon":{"lon":-1085716794,"lat":416454065}}},{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416344087,"long":-1082586926}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31551}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024175,"speed":24.14,"longitude":-105.0476338},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":55,"serialNumber":15484,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31448,"packetID":"000000000000078022","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416786287,"long":-1087839399},"name":"eastbound_I80_130.84_142.17_SAT-7FA0318B_RC_PDI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1087821508,"lat":416782598}}},{"delta":{"node-LatLon":{"lon":-1087803620,"lat":416778902}}},{"delta":{"node-LatLon":{"lon":-1087765168,"lat":416771009}}},{"delta":{"node-LatLon":{"lon":-1087726370,"lat":416764174}}},{"delta":{"node-LatLon":{"lon":-1087686884,"lat":416760144}}},{"delta":{"node-LatLon":{"lon":-1087647203,"lat":416757279}}},{"delta":{"node-LatLon":{"lon":-1087607525,"lat":416754383}}},{"delta":{"node-LatLon":{"lon":-1087569186,"lat":416751628}}},{"delta":{"node-LatLon":{"lon":-1087530855,"lat":416748818}}},{"delta":{"node-LatLon":{"lon":-1087492521,"lat":416746033}}},{"delta":{"node-LatLon":{"lon":-1087454195,"lat":416743189}}},{"delta":{"node-LatLon":{"lon":-1087416702,"lat":416736770}}},{"delta":{"node-LatLon":{"lon":-1087381435,"lat":416725340}}},{"delta":{"node-LatLon":{"lon":-1087349578,"lat":416709238}}},{"delta":{"node-LatLon":{"lon":-1087320577,"lat":416690280}}},{"delta":{"node-LatLon":{"lon":-1087291648,"lat":416671260}}},{"delta":{"node-LatLon":{"lon":-1087262787,"lat":416652182}}},{"delta":{"node-LatLon":{"lon":-1087233802,"lat":416633016}}},{"delta":{"node-LatLon":{"lon":-1087204787,"lat":416613876}}},{"delta":{"node-LatLon":{"lon":-1087175815,"lat":416594699}}},{"delta":{"node-LatLon":{"lon":-1087146808,"lat":416575554}}},{"delta":{"node-LatLon":{"lon":-1087117854,"lat":416556364}}},{"delta":{"node-LatLon":{"lon":-1087088159,"lat":416538069}}},{"delta":{"node-LatLon":{"lon":-1087056409,"lat":416521833}}},{"delta":{"node-LatLon":{"lon":-1087022859,"lat":416507786}}},{"delta":{"node-LatLon":{"lon":-1086987709,"lat":416496142}}},{"delta":{"node-LatLon":{"lon":-1086951310,"lat":416486912}}},{"delta":{"node-LatLon":{"lon":-1086913467,"lat":416480171}}},{"delta":{"node-LatLon":{"lon":-1086874956,"lat":416476074}}},{"delta":{"node-LatLon":{"lon":-1086836114,"lat":416474482}}},{"delta":{"node-LatLon":{"lon":-1086797232,"lat":416473404}}},{"delta":{"node-LatLon":{"lon":-1086758350,"lat":416472330}}},{"delta":{"node-LatLon":{"lon":-1086719468,"lat":416471283}}},{"delta":{"node-LatLon":{"lon":-1086680585,"lat":416470225}}},{"delta":{"node-LatLon":{"lon":-1086641702,"lat":416469187}}},{"delta":{"node-LatLon":{"lon":-1086602819,"lat":416468148}}},{"delta":{"node-LatLon":{"lon":-1086563936,"lat":416467108}}},{"delta":{"node-LatLon":{"lon":-1086525511,"lat":416466317}}},{"delta":{"node-LatLon":{"lon":-1086487125,"lat":416467788}}},{"delta":{"node-LatLon":{"lon":-1086448944,"lat":416471177}}},{"delta":{"node-LatLon":{"lon":-1086410780,"lat":416474681}}},{"delta":{"node-LatLon":{"lon":-1086372613,"lat":416478166}}},{"delta":{"node-LatLon":{"lon":-1086334405,"lat":416481678}}},{"delta":{"node-LatLon":{"lon":-1086296197,"lat":416485199}}},{"delta":{"node-LatLon":{"lon":-1086257994,"lat":416488743}}},{"delta":{"node-LatLon":{"lon":-1086219779,"lat":416492224}}},{"delta":{"node-LatLon":{"lon":-1086181504,"lat":416495268}}},{"delta":{"node-LatLon":{"lon":-1086142990,"lat":416495887}}},{"delta":{"node-LatLon":{"lon":-1086104564,"lat":416493848}}},{"delta":{"node-LatLon":{"lon":-1086066501,"lat":416489365}}},{"delta":{"node-LatLon":{"lon":-1086028512,"lat":416484522}}},{"delta":{"node-LatLon":{"lon":-1085990518,"lat":416479699}}},{"delta":{"node-LatLon":{"lon":-1085952503,"lat":416474853}}},{"delta":{"node-LatLon":{"lon":-1085914496,"lat":416469967}}},{"delta":{"node-LatLon":{"lon":-1085876481,"lat":416465123}}},{"delta":{"node-LatLon":{"lon":-1085838471,"lat":416460258}}},{"delta":{"node-LatLon":{"lon":-1085800440,"lat":416455490}}},{"delta":{"node-LatLon":{"lon":-1085761374,"lat":416452277}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416786287,"long":-1087839399}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31448}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024218,"speed":24.14,"longitude":-105.0476056},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":57,"serialNumber":15486,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:10.051Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31551,"packetID":"00000000000004E0EC","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416455490,"long":-1085800440},"name":"eastbound_I80_142.17_158.55_SAT-A139FA35_RC_PDI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085780958,"lat":416453533}}},{"delta":{"node-LatLon":{"lon":-1085722182,"lat":416449943}}},{"delta":{"node-LatLon":{"lon":-1085643804,"lat":416445230}}},{"delta":{"node-LatLon":{"lon":-1085565424,"lat":416440540}}},{"delta":{"node-LatLon":{"lon":-1085487043,"lat":416435869}}},{"delta":{"node-LatLon":{"lon":-1085408668,"lat":416431146}}},{"delta":{"node-LatLon":{"lon":-1085330293,"lat":416426421}}},{"delta":{"node-LatLon":{"lon":-1085251916,"lat":416421727}}},{"delta":{"node-LatLon":{"lon":-1085173902,"lat":416416997}}},{"delta":{"node-LatLon":{"lon":-1085096242,"lat":416412330}}},{"delta":{"node-LatLon":{"lon":-1085018585,"lat":416407636}}},{"delta":{"node-LatLon":{"lon":-1084940663,"lat":416402897}}},{"delta":{"node-LatLon":{"lon":-1084862741,"lat":416398163}}},{"delta":{"node-LatLon":{"lon":-1084784815,"lat":416393472}}},{"delta":{"node-LatLon":{"lon":-1084706889,"lat":416388787}}},{"delta":{"node-LatLon":{"lon":-1084628972,"lat":416384031}}},{"delta":{"node-LatLon":{"lon":-1084551057,"lat":416379343}}},{"delta":{"node-LatLon":{"lon":-1084473154,"lat":416374560}}},{"delta":{"node-LatLon":{"lon":-1084399541,"lat":416370085}}},{"delta":{"node-LatLon":{"lon":-1084330227,"lat":416365845}}},{"delta":{"node-LatLon":{"lon":-1084260912,"lat":416361623}}},{"delta":{"node-LatLon":{"lon":-1084184275,"lat":416356906}}},{"delta":{"node-LatLon":{"lon":-1084107548,"lat":416353136}}},{"delta":{"node-LatLon":{"lon":-1084030065,"lat":416348811}}},{"delta":{"node-LatLon":{"lon":-1083951951,"lat":416342842}}},{"delta":{"node-LatLon":{"lon":-1083873709,"lat":416337915}}},{"delta":{"node-LatLon":{"lon":-1083796972,"lat":416333186}}},{"delta":{"node-LatLon":{"lon":-1083720234,"lat":416328459}}},{"delta":{"node-LatLon":{"lon":-1083643497,"lat":416323733}}},{"delta":{"node-LatLon":{"lon":-1083566759,"lat":416319020}}},{"delta":{"node-LatLon":{"lon":-1083489868,"lat":416316067}}},{"delta":{"node-LatLon":{"lon":-1083413019,"lat":416313460}}},{"delta":{"node-LatLon":{"lon":-1083336178,"lat":416310750}}},{"delta":{"node-LatLon":{"lon":-1083259199,"lat":416308063}}},{"delta":{"node-LatLon":{"lon":-1083182086,"lat":416305377}}},{"delta":{"node-LatLon":{"lon":-1083104978,"lat":416302622}}},{"delta":{"node-LatLon":{"lon":-1083028061,"lat":416299895}}},{"delta":{"node-LatLon":{"lon":-1082951147,"lat":416297144}}},{"delta":{"node-LatLon":{"lon":-1082873751,"lat":416296812}}},{"delta":{"node-LatLon":{"lon":-1082797210,"lat":416308158}}},{"delta":{"node-LatLon":{"lon":-1082720795,"lat":416320017}}},{"delta":{"node-LatLon":{"lon":-1082645377,"lat":416331711}}},{"delta":{"node-LatLon":{"lon":-1082607675,"lat":416337584}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416455490,"long":-1085800440}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31551}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024218,"speed":24.14,"longitude":-105.0476056},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":56,"serialNumber":15485,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31448,"packetID":"00000000000008DC26","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416456408,"long":-1085755840},"name":"westbound_I80_130.84_142.17_SAT-84100418_RC_PDI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}},{"delta":{"node-LatLon":{"lon":-1085794888,"lat":416458736}}},{"delta":{"node-LatLon":{"lon":-1085833690,"lat":416461832}}},{"delta":{"node-LatLon":{"lon":-1085872176,"lat":416466707}}},{"delta":{"node-LatLon":{"lon":-1085910651,"lat":416471634}}},{"delta":{"node-LatLon":{"lon":-1085949134,"lat":416476528}}},{"delta":{"node-LatLon":{"lon":-1085987613,"lat":416481440}}},{"delta":{"node-LatLon":{"lon":-1086025528,"lat":416486267}}},{"delta":{"node-LatLon":{"lon":-1086063443,"lat":416491103}}},{"delta":{"node-LatLon":{"lon":-1086101422,"lat":416495630}}},{"delta":{"node-LatLon":{"lon":-1086139754,"lat":416497851}}},{"delta":{"node-LatLon":{"lon":-1086178196,"lat":416497493}}},{"delta":{"node-LatLon":{"lon":-1086216694,"lat":416494658}}},{"delta":{"node-LatLon":{"lon":-1086255095,"lat":416491116}}},{"delta":{"node-LatLon":{"lon":-1086293500,"lat":416487604}}},{"delta":{"node-LatLon":{"lon":-1086331905,"lat":416484089}}},{"delta":{"node-LatLon":{"lon":-1086370307,"lat":416480557}}},{"delta":{"node-LatLon":{"lon":-1086408427,"lat":416477034}}},{"delta":{"node-LatLon":{"lon":-1086446550,"lat":416473535}}},{"delta":{"node-LatLon":{"lon":-1086484678,"lat":416470066}}},{"delta":{"node-LatLon":{"lon":-1086523010,"lat":416468441}}},{"delta":{"node-LatLon":{"lon":-1086561402,"lat":416469144}}},{"delta":{"node-LatLon":{"lon":-1086600122,"lat":416470197}}},{"delta":{"node-LatLon":{"lon":-1086638841,"lat":416471267}}},{"delta":{"node-LatLon":{"lon":-1086677561,"lat":416472320}}},{"delta":{"node-LatLon":{"lon":-1086716282,"lat":416473363}}},{"delta":{"node-LatLon":{"lon":-1086755004,"lat":416474397}}},{"delta":{"node-LatLon":{"lon":-1086793804,"lat":416475422}}},{"delta":{"node-LatLon":{"lon":-1086832605,"lat":416476448}}},{"delta":{"node-LatLon":{"lon":-1086871382,"lat":416477827}}},{"delta":{"node-LatLon":{"lon":-1086909854,"lat":416481660}}},{"delta":{"node-LatLon":{"lon":-1086947668,"lat":416488224}}},{"delta":{"node-LatLon":{"lon":-1086984094,"lat":416497241}}},{"delta":{"node-LatLon":{"lon":-1087019268,"lat":416508718}}},{"delta":{"node-LatLon":{"lon":-1087052913,"lat":416522538}}},{"delta":{"node-LatLon":{"lon":-1087084695,"lat":416538656}}},{"delta":{"node-LatLon":{"lon":-1087114440,"lat":416556828}}},{"delta":{"node-LatLon":{"lon":-1087143191,"lat":416575895}}},{"delta":{"node-LatLon":{"lon":-1087171993,"lat":416594919}}},{"delta":{"node-LatLon":{"lon":-1087200784,"lat":416613953}}},{"delta":{"node-LatLon":{"lon":-1087229590,"lat":416632975}}},{"delta":{"node-LatLon":{"lon":-1087258414,"lat":416651983}}},{"delta":{"node-LatLon":{"lon":-1087287411,"lat":416671131}}},{"delta":{"node-LatLon":{"lon":-1087316426,"lat":416690264}}},{"delta":{"node-LatLon":{"lon":-1087345506,"lat":416709342}}},{"delta":{"node-LatLon":{"lon":-1087377220,"lat":416725818}}},{"delta":{"node-LatLon":{"lon":-1087412334,"lat":416737800}}},{"delta":{"node-LatLon":{"lon":-1087450059,"lat":416744739}}},{"delta":{"node-LatLon":{"lon":-1087488730,"lat":416747863}}},{"delta":{"node-LatLon":{"lon":-1087527450,"lat":416750657}}},{"delta":{"node-LatLon":{"lon":-1087566170,"lat":416753452}}},{"delta":{"node-LatLon":{"lon":-1087604889,"lat":416756257}}},{"delta":{"node-LatLon":{"lon":-1087644394,"lat":416759090}}},{"delta":{"node-LatLon":{"lon":-1087683889,"lat":416761997}}},{"delta":{"node-LatLon":{"lon":-1087723223,"lat":416765852}}},{"delta":{"node-LatLon":{"lon":-1087761910,"lat":416772440}}},{"delta":{"node-LatLon":{"lon":-1087800160,"lat":416780373}}},{"delta":{"node-LatLon":{"lon":-1087836031,"lat":416787816}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416456408,"long":-1085755840}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31448}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6375,"latitude":41.1024175,"speed":24.14,"longitude":-105.0476338},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":54,"serialNumber":15483,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31205,"packetID":"000000000000053EE5","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415560658,"long":-1095891000},"name":"westbound_I80_66.17_83.01_SAT-B436F4C6_RC_GRAI80ERSD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1095909369,"lat":415556119}}},{"delta":{"node-LatLon":{"lon":-1095944107,"lat":415543430}}},{"delta":{"node-LatLon":{"lon":-1096006459,"lat":415509058}}},{"delta":{"node-LatLon":{"lon":-1096069455,"lat":415475411}}},{"delta":{"node-LatLon":{"lon":-1096142938,"lat":415458428}}},{"delta":{"node-LatLon":{"lon":-1096220131,"lat":415454351}}},{"delta":{"node-LatLon":{"lon":-1096297661,"lat":415450429}}},{"delta":{"node-LatLon":{"lon":-1096375509,"lat":415446500}}},{"delta":{"node-LatLon":{"lon":-1096453356,"lat":415442570}}},{"delta":{"node-LatLon":{"lon":-1096529793,"lat":415438718}}},{"delta":{"node-LatLon":{"lon":-1096606229,"lat":415434853}}},{"delta":{"node-LatLon":{"lon":-1096682818,"lat":415430949}}},{"delta":{"node-LatLon":{"lon":-1096759566,"lat":415427053}}},{"delta":{"node-LatLon":{"lon":-1096836470,"lat":415426618}}},{"delta":{"node-LatLon":{"lon":-1096912173,"lat":415426953}}},{"delta":{"node-LatLon":{"lon":-1096987876,"lat":415427245}}},{"delta":{"node-LatLon":{"lon":-1097064311,"lat":415427583}}},{"delta":{"node-LatLon":{"lon":-1097141481,"lat":415427878}}},{"delta":{"node-LatLon":{"lon":-1097218650,"lat":415428173}}},{"delta":{"node-LatLon":{"lon":-1097295910,"lat":415428433}}},{"delta":{"node-LatLon":{"lon":-1097373170,"lat":415428724}}},{"delta":{"node-LatLon":{"lon":-1097450254,"lat":415429029}}},{"delta":{"node-LatLon":{"lon":-1097527162,"lat":415429272}}},{"delta":{"node-LatLon":{"lon":-1097604070,"lat":415429555}}},{"delta":{"node-LatLon":{"lon":-1097681194,"lat":415429816}}},{"delta":{"node-LatLon":{"lon":-1097758318,"lat":415430084}}},{"delta":{"node-LatLon":{"lon":-1097835692,"lat":415430343}}},{"delta":{"node-LatLon":{"lon":-1097913317,"lat":415430599}}},{"delta":{"node-LatLon":{"lon":-1097990942,"lat":415430851}}},{"delta":{"node-LatLon":{"lon":-1098065366,"lat":415431126}}},{"delta":{"node-LatLon":{"lon":-1098139791,"lat":415431337}}},{"delta":{"node-LatLon":{"lon":-1098216745,"lat":415431535}}},{"delta":{"node-LatLon":{"lon":-1098296228,"lat":415431795}}},{"delta":{"node-LatLon":{"lon":-1098375702,"lat":415431381}}},{"delta":{"node-LatLon":{"lon":-1098453162,"lat":415429222}}},{"delta":{"node-LatLon":{"lon":-1098530622,"lat":415427098}}},{"delta":{"node-LatLon":{"lon":-1098607730,"lat":415424827}}},{"delta":{"node-LatLon":{"lon":-1098684499,"lat":415422667}}},{"delta":{"node-LatLon":{"lon":-1098761268,"lat":415420511}}},{"delta":{"node-LatLon":{"lon":-1098838221,"lat":415418364}}},{"delta":{"node-LatLon":{"lon":-1098914903,"lat":415422678}}},{"delta":{"node-LatLon":{"lon":-1098990040,"lat":415435886}}},{"delta":{"node-LatLon":{"lon":-1099066262,"lat":415444919}}},{"delta":{"node-LatLon":{"lon":-1099124034,"lat":415441676}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415560658,"long":-1095891000}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31205}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024175,"speed":24.02,"longitude":-105.0476341},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":53,"serialNumber":15482,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000C0531","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415436014,"long":-1099144153},"name":"eastbound_I80_66.17_83.01_SAT-C94BB8D8_RC_GRAI80ERSI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1099125634,"lat":415439288}}},{"delta":{"node-LatLon":{"lon":-1099068840,"lat":415442454}}},{"delta":{"node-LatLon":{"lon":-1098994159,"lat":415432068}}},{"delta":{"node-LatLon":{"lon":-1098919298,"lat":415418672}}},{"delta":{"node-LatLon":{"lon":-1098841848,"lat":415413814}}},{"delta":{"node-LatLon":{"lon":-1098764064,"lat":415415860}}},{"delta":{"node-LatLon":{"lon":-1098686825,"lat":415418104}}},{"delta":{"node-LatLon":{"lon":-1098609587,"lat":415420386}}},{"delta":{"node-LatLon":{"lon":-1098532251,"lat":415422458}}},{"delta":{"node-LatLon":{"lon":-1098454828,"lat":415424612}}},{"delta":{"node-LatLon":{"lon":-1098377407,"lat":415426813}}},{"delta":{"node-LatLon":{"lon":-1098298392,"lat":415427231}}},{"delta":{"node-LatLon":{"lon":-1098219367,"lat":415427018}}},{"delta":{"node-LatLon":{"lon":-1098142482,"lat":415426813}}},{"delta":{"node-LatLon":{"lon":-1098067736,"lat":415426561}}},{"delta":{"node-LatLon":{"lon":-1097992991,"lat":415426314}}},{"delta":{"node-LatLon":{"lon":-1097915737,"lat":415426054}}},{"delta":{"node-LatLon":{"lon":-1097838483,"lat":415425798}}},{"delta":{"node-LatLon":{"lon":-1097761247,"lat":415425574}}},{"delta":{"node-LatLon":{"lon":-1097684029,"lat":415425298}}},{"delta":{"node-LatLon":{"lon":-1097606811,"lat":415425006}}},{"delta":{"node-LatLon":{"lon":-1097529582,"lat":415424747}}},{"delta":{"node-LatLon":{"lon":-1097452354,"lat":415424479}}},{"delta":{"node-LatLon":{"lon":-1097375180,"lat":415424173}}},{"delta":{"node-LatLon":{"lon":-1097298061,"lat":415423892}}},{"delta":{"node-LatLon":{"lon":-1097220943,"lat":415423592}}},{"delta":{"node-LatLon":{"lon":-1097143863,"lat":415423302}}},{"delta":{"node-LatLon":{"lon":-1097066784,"lat":415423022}}},{"delta":{"node-LatLon":{"lon":-1096989920,"lat":415422730}}},{"delta":{"node-LatLon":{"lon":-1096913273,"lat":415422418}}},{"delta":{"node-LatLon":{"lon":-1096836626,"lat":415422122}}},{"delta":{"node-LatLon":{"lon":-1096759032,"lat":415422540}}},{"delta":{"node-LatLon":{"lon":-1096681595,"lat":415426454}}},{"delta":{"node-LatLon":{"lon":-1096604890,"lat":415430398}}},{"delta":{"node-LatLon":{"lon":-1096528903,"lat":415434233}}},{"delta":{"node-LatLon":{"lon":-1096452915,"lat":415438069}}},{"delta":{"node-LatLon":{"lon":-1096375022,"lat":415442012}}},{"delta":{"node-LatLon":{"lon":-1096297130,"lat":415445968}}},{"delta":{"node-LatLon":{"lon":-1096219868,"lat":415449865}}},{"delta":{"node-LatLon":{"lon":-1096143253,"lat":415453868}}},{"delta":{"node-LatLon":{"lon":-1096070093,"lat":415470372}}},{"delta":{"node-LatLon":{"lon":-1096006307,"lat":415503454}}},{"delta":{"node-LatLon":{"lon":-1095944191,"lat":415538433}}},{"delta":{"node-LatLon":{"lon":-1095892161,"lat":415557599}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415436014,"long":-1099144153}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024175,"speed":24.02,"longitude":-105.0476341},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":52,"serialNumber":15481,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31214,"packetID":"0000000000000B2F91","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413575987,"long":-1103362302},"name":"westbound_I80_30.4_39.9_SAT-81C57B76_RC_LYMI80WEVAND","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1103379413,"lat":413570507}}},{"delta":{"node-LatLon":{"lon":-1103396581,"lat":413565130}}},{"delta":{"node-LatLon":{"lon":-1103431966,"lat":413556590}}},{"delta":{"node-LatLon":{"lon":-1103468559,"lat":413551740}}},{"delta":{"node-LatLon":{"lon":-1103505682,"lat":413550496}}},{"delta":{"node-LatLon":{"lon":-1103542862,"lat":413550244}}},{"delta":{"node-LatLon":{"lon":-1103582724,"lat":413550041}}},{"delta":{"node-LatLon":{"lon":-1103622586,"lat":413549804}}},{"delta":{"node-LatLon":{"lon":-1103662427,"lat":413549039}}},{"delta":{"node-LatLon":{"lon":-1103701626,"lat":413543839}}},{"delta":{"node-LatLon":{"lon":-1103738811,"lat":413533136}}},{"delta":{"node-LatLon":{"lon":-1103772015,"lat":413518736}}},{"delta":{"node-LatLon":{"lon":-1103804719,"lat":413503676}}},{"delta":{"node-LatLon":{"lon":-1103837423,"lat":413488615}}},{"delta":{"node-LatLon":{"lon":-1103870139,"lat":413473571}}},{"delta":{"node-LatLon":{"lon":-1103902852,"lat":413458525}}},{"delta":{"node-LatLon":{"lon":-1103935453,"lat":413443497}}},{"delta":{"node-LatLon":{"lon":-1103968058,"lat":413428474}}},{"delta":{"node-LatLon":{"lon":-1104000677,"lat":413413470}}},{"delta":{"node-LatLon":{"lon":-1104033300,"lat":413398472}}},{"delta":{"node-LatLon":{"lon":-1104066139,"lat":413383747}}},{"delta":{"node-LatLon":{"lon":-1104099921,"lat":413369977}}},{"delta":{"node-LatLon":{"lon":-1104134521,"lat":413357416}}},{"delta":{"node-LatLon":{"lon":-1104169857,"lat":413346086}}},{"delta":{"node-LatLon":{"lon":-1104205824,"lat":413335944}}},{"delta":{"node-LatLon":{"lon":-1104242388,"lat":413327102}}},{"delta":{"node-LatLon":{"lon":-1104279634,"lat":413319406}}},{"delta":{"node-LatLon":{"lon":-1104317320,"lat":413313051}}},{"delta":{"node-LatLon":{"lon":-1104355343,"lat":413307943}}},{"delta":{"node-LatLon":{"lon":-1104393408,"lat":413303019}}},{"delta":{"node-LatLon":{"lon":-1104431463,"lat":413298050}}},{"delta":{"node-LatLon":{"lon":-1104469251,"lat":413293160}}},{"delta":{"node-LatLon":{"lon":-1104507032,"lat":413288242}}},{"delta":{"node-LatLon":{"lon":-1104544821,"lat":413283359}}},{"delta":{"node-LatLon":{"lon":-1104582614,"lat":413278496}}},{"delta":{"node-LatLon":{"lon":-1104620358,"lat":413273425}}},{"delta":{"node-LatLon":{"lon":-1104657693,"lat":413266409}}},{"delta":{"node-LatLon":{"lon":-1104694040,"lat":413256888}}},{"delta":{"node-LatLon":{"lon":-1104729409,"lat":413245439}}},{"delta":{"node-LatLon":{"lon":-1104764689,"lat":413233834}}},{"delta":{"node-LatLon":{"lon":-1104799973,"lat":413222237}}},{"delta":{"node-LatLon":{"lon":-1104835095,"lat":413210680}}},{"delta":{"node-LatLon":{"lon":-1104870213,"lat":413199116}}},{"delta":{"node-LatLon":{"lon":-1104905341,"lat":413187570}}},{"delta":{"node-LatLon":{"lon":-1104940464,"lat":413176017}}},{"delta":{"node-LatLon":{"lon":-1104975588,"lat":413164466}}},{"delta":{"node-LatLon":{"lon":-1105010940,"lat":413152841}}},{"delta":{"node-LatLon":{"lon":-1105046305,"lat":413141239}}},{"delta":{"node-LatLon":{"lon":-1105081636,"lat":413129581}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000110000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413575987,"long":-1103362302}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31214}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024133,"speed":24.02,"longitude":-105.0476621},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":51,"serialNumber":15480,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"00000000000008948B","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413121024,"long":-1105099337},"name":"eastbound_I80_30.4_39.9_SAT-2B017F7E_RC_LYMI80WEVANI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1105081780,"lat":413126737}}},{"delta":{"node-LatLon":{"lon":-1105046721,"lat":413138259}}},{"delta":{"node-LatLon":{"lon":-1105011682,"lat":413149818}}},{"delta":{"node-LatLon":{"lon":-1104976636,"lat":413161366}}},{"delta":{"node-LatLon":{"lon":-1104941339,"lat":413172988}}},{"delta":{"node-LatLon":{"lon":-1104906045,"lat":413184616}}},{"delta":{"node-LatLon":{"lon":-1104870749,"lat":413196242}}},{"delta":{"node-LatLon":{"lon":-1104835431,"lat":413207831}}},{"delta":{"node-LatLon":{"lon":-1104800118,"lat":413219429}}},{"delta":{"node-LatLon":{"lon":-1104764982,"lat":413230978}}},{"delta":{"node-LatLon":{"lon":-1104729863,"lat":413242558}}},{"delta":{"node-LatLon":{"lon":-1104694662,"lat":413253995}}},{"delta":{"node-LatLon":{"lon":-1104658541,"lat":413263634}}},{"delta":{"node-LatLon":{"lon":-1104621387,"lat":413270688}}},{"delta":{"node-LatLon":{"lon":-1104583599,"lat":413275784}}},{"delta":{"node-LatLon":{"lon":-1104545768,"lat":413280701}}},{"delta":{"node-LatLon":{"lon":-1104507932,"lat":413285595}}},{"delta":{"node-LatLon":{"lon":-1104470107,"lat":413290537}}},{"delta":{"node-LatLon":{"lon":-1104432261,"lat":413295393}}},{"delta":{"node-LatLon":{"lon":-1104394348,"lat":413300372}}},{"delta":{"node-LatLon":{"lon":-1104356408,"lat":413305233}}},{"delta":{"node-LatLon":{"lon":-1104318509,"lat":413310273}}},{"delta":{"node-LatLon":{"lon":-1104280839,"lat":413316200}}},{"delta":{"node-LatLon":{"lon":-1104243586,"lat":413323475}}},{"delta":{"node-LatLon":{"lon":-1104206850,"lat":413331998}}},{"delta":{"node-LatLon":{"lon":-1104170685,"lat":413341807}}},{"delta":{"node-LatLon":{"lon":-1104135154,"lat":413352860}}},{"delta":{"node-LatLon":{"lon":-1104100355,"lat":413365166}}},{"delta":{"node-LatLon":{"lon":-1104066322,"lat":413378639}}},{"delta":{"node-LatLon":{"lon":-1104032685,"lat":413393491}}},{"delta":{"node-LatLon":{"lon":-1103999387,"lat":413408776}}},{"delta":{"node-LatLon":{"lon":-1103966118,"lat":413424098}}},{"delta":{"node-LatLon":{"lon":-1103932864,"lat":413439440}}},{"delta":{"node-LatLon":{"lon":-1103899565,"lat":413454727}}},{"delta":{"node-LatLon":{"lon":-1103867253,"lat":413469609}}},{"delta":{"node-LatLon":{"lon":-1103835035,"lat":413484430}}},{"delta":{"node-LatLon":{"lon":-1103802824,"lat":413499260}}},{"delta":{"node-LatLon":{"lon":-1103770586,"lat":413514056}}},{"delta":{"node-LatLon":{"lon":-1103738028,"lat":413528436}}},{"delta":{"node-LatLon":{"lon":-1103701332,"lat":413539215}}},{"delta":{"node-LatLon":{"lon":-1103662594,"lat":413544545}}},{"delta":{"node-LatLon":{"lon":-1103623171,"lat":413545277}}},{"delta":{"node-LatLon":{"lon":-1103583727,"lat":413545520}}},{"delta":{"node-LatLon":{"lon":-1103544283,"lat":413545768}}},{"delta":{"node-LatLon":{"lon":-1103506786,"lat":413545969}}},{"delta":{"node-LatLon":{"lon":-1103469334,"lat":413547162}}},{"delta":{"node-LatLon":{"lon":-1103432403,"lat":413551942}}},{"delta":{"node-LatLon":{"lon":-1103396637,"lat":413560362}}},{"delta":{"node-LatLon":{"lon":-1103379293,"lat":413565730}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413121024,"long":-1105099337}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":22}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":47,"serialNumber":15476,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.453Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000B2362","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414323150,"long":-1101107194},"name":"eastbound_I80_53.31_66.17_SAT-19D61E53_RC_GRAI80WLYMI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1101089557,"lat":414329241}}},{"delta":{"node-LatLon":{"lon":-1101036650,"lat":414347521}}},{"delta":{"node-LatLon":{"lon":-1100968154,"lat":414374868}}},{"delta":{"node-LatLon":{"lon":-1100906030,"lat":414408931}}},{"delta":{"node-LatLon":{"lon":-1100844476,"lat":414443598}}},{"delta":{"node-LatLon":{"lon":-1100783084,"lat":414478183}}},{"delta":{"node-LatLon":{"lon":-1100721845,"lat":414512678}}},{"delta":{"node-LatLon":{"lon":-1100660589,"lat":414547159}}},{"delta":{"node-LatLon":{"lon":-1100598696,"lat":414582011}}},{"delta":{"node-LatLon":{"lon":-1100536824,"lat":414616882}}},{"delta":{"node-LatLon":{"lon":-1100472780,"lat":414652911}}},{"delta":{"node-LatLon":{"lon":-1100407893,"lat":414691351}}},{"delta":{"node-LatLon":{"lon":-1100352218,"lat":414737180}}},{"delta":{"node-LatLon":{"lon":-1100303788,"lat":414782434}}},{"delta":{"node-LatLon":{"lon":-1100255356,"lat":414827689}}},{"delta":{"node-LatLon":{"lon":-1100207264,"lat":414872624}}},{"delta":{"node-LatLon":{"lon":-1100156738,"lat":414915457}}},{"delta":{"node-LatLon":{"lon":-1100105308,"lat":414957699}}},{"delta":{"node-LatLon":{"lon":-1100048563,"lat":414996592}}},{"delta":{"node-LatLon":{"lon":-1099984833,"lat":415028931}}},{"delta":{"node-LatLon":{"lon":-1099920979,"lat":415061041}}},{"delta":{"node-LatLon":{"lon":-1099857029,"lat":415092941}}},{"delta":{"node-LatLon":{"lon":-1099792739,"lat":415124448}}},{"delta":{"node-LatLon":{"lon":-1099728759,"lat":415156288}}},{"delta":{"node-LatLon":{"lon":-1099664735,"lat":415188081}}},{"delta":{"node-LatLon":{"lon":-1099600327,"lat":415220093}}},{"delta":{"node-LatLon":{"lon":-1099535522,"lat":415252310}}},{"delta":{"node-LatLon":{"lon":-1099470701,"lat":415284512}}},{"delta":{"node-LatLon":{"lon":-1099406151,"lat":415316553}}},{"delta":{"node-LatLon":{"lon":-1099341572,"lat":415348565}}},{"delta":{"node-LatLon":{"lon":-1099277375,"lat":415380463}}},{"delta":{"node-LatLon":{"lon":-1099213464,"lat":415412136}}},{"delta":{"node-LatLon":{"lon":-1099144153,"lat":415436014}}},{"delta":{"node-LatLon":{"lon":-1099106846,"lat":415441537}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111000000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414323150,"long":-1101107194}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.1024133,"speed":24.02,"longitude":-105.0476621},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":50,"serialNumber":15479,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31214,"packetID":"0000000000000A659A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414344751,"long":-1101051424},"name":"westbound_I80_39.9_53.31_SAT-08844513_RC_LYMI80EGRAD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1101068786,"lat":414338729}}},{"delta":{"node-LatLon":{"lon":-1101103554,"lat":414326761}}},{"delta":{"node-LatLon":{"lon":-1101173821,"lat":414302516}}},{"delta":{"node-LatLon":{"lon":-1101244744,"lat":414277845}}},{"delta":{"node-LatLon":{"lon":-1101310950,"lat":414246773}}},{"delta":{"node-LatLon":{"lon":-1101362064,"lat":414212123}}},{"delta":{"node-LatLon":{"lon":-1101407558,"lat":414173212}}},{"delta":{"node-LatLon":{"lon":-1101456142,"lat":414132500}}},{"delta":{"node-LatLon":{"lon":-1101515051,"lat":414095801}}},{"delta":{"node-LatLon":{"lon":-1101578308,"lat":414063326}}},{"delta":{"node-LatLon":{"lon":-1101641229,"lat":414030925}}},{"delta":{"node-LatLon":{"lon":-1101704290,"lat":413998477}}},{"delta":{"node-LatLon":{"lon":-1101767097,"lat":413966110}}},{"delta":{"node-LatLon":{"lon":-1101831402,"lat":413935792}}},{"delta":{"node-LatLon":{"lon":-1101901550,"lat":413914120}}},{"delta":{"node-LatLon":{"lon":-1101976786,"lat":413898894}}},{"delta":{"node-LatLon":{"lon":-1102052080,"lat":413883827}}},{"delta":{"node-LatLon":{"lon":-1102126907,"lat":413868839}}},{"delta":{"node-LatLon":{"lon":-1102200439,"lat":413851903}}},{"delta":{"node-LatLon":{"lon":-1102269103,"lat":413825929}}},{"delta":{"node-LatLon":{"lon":-1102332567,"lat":413793094}}},{"delta":{"node-LatLon":{"lon":-1102398732,"lat":413763591}}},{"delta":{"node-LatLon":{"lon":-1102470298,"lat":413743958}}},{"delta":{"node-LatLon":{"lon":-1102543982,"lat":413731406}}},{"delta":{"node-LatLon":{"lon":-1102617848,"lat":413719488}}},{"delta":{"node-LatLon":{"lon":-1102692470,"lat":413710650}}},{"delta":{"node-LatLon":{"lon":-1102767178,"lat":413702215}}},{"delta":{"node-LatLon":{"lon":-1102843114,"lat":413693602}}},{"delta":{"node-LatLon":{"lon":-1102920289,"lat":413684874}}},{"delta":{"node-LatLon":{"lon":-1102996200,"lat":413671478}}},{"delta":{"node-LatLon":{"lon":-1103069136,"lat":413655627}}},{"delta":{"node-LatLon":{"lon":-1103142026,"lat":413639808}}},{"delta":{"node-LatLon":{"lon":-1103216030,"lat":413622306}}},{"delta":{"node-LatLon":{"lon":-1103289209,"lat":413599223}}},{"delta":{"node-LatLon":{"lon":-1103362302,"lat":413575987}}},{"delta":{"node-LatLon":{"lon":-1103379413,"lat":413570507}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001110000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414344751,"long":-1101051424}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31214}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.65,"latitude":41.102409,"speed":24.02,"longitude":-105.0476902},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":49,"serialNumber":15478,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000019B21","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413560362,"long":-1103396637},"name":"eastbound_I80_39.9_53.31_SAT-A835ACAE_RC_LYMI80EGRAI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1103379293,"lat":413565730}}},{"delta":{"node-LatLon":{"lon":-1103362018,"lat":413571225}}},{"delta":{"node-LatLon":{"lon":-1103289477,"lat":413594336}}},{"delta":{"node-LatLon":{"lon":-1103216886,"lat":413617361}}},{"delta":{"node-LatLon":{"lon":-1103144075,"lat":413634764}}},{"delta":{"node-LatLon":{"lon":-1103072890,"lat":413650240}}},{"delta":{"node-LatLon":{"lon":-1103001562,"lat":413665711}}},{"delta":{"node-LatLon":{"lon":-1102924478,"lat":413679917}}},{"delta":{"node-LatLon":{"lon":-1102845931,"lat":413688783}}},{"delta":{"node-LatLon":{"lon":-1102769203,"lat":413697491}}},{"delta":{"node-LatLon":{"lon":-1102694282,"lat":413705973}}},{"delta":{"node-LatLon":{"lon":-1102619427,"lat":413714771}}},{"delta":{"node-LatLon":{"lon":-1102543987,"lat":413726889}}},{"delta":{"node-LatLon":{"lon":-1102468757,"lat":413739737}}},{"delta":{"node-LatLon":{"lon":-1102396564,"lat":413759508}}},{"delta":{"node-LatLon":{"lon":-1102330529,"lat":413788757}}},{"delta":{"node-LatLon":{"lon":-1102267374,"lat":413821547}}},{"delta":{"node-LatLon":{"lon":-1102198471,"lat":413847770}}},{"delta":{"node-LatLon":{"lon":-1102124566,"lat":413864728}}},{"delta":{"node-LatLon":{"lon":-1102050308,"lat":413879597}}},{"delta":{"node-LatLon":{"lon":-1101976512,"lat":413894383}}},{"delta":{"node-LatLon":{"lon":-1101902756,"lat":413909284}}},{"delta":{"node-LatLon":{"lon":-1101831568,"lat":413930764}}},{"delta":{"node-LatLon":{"lon":-1101766297,"lat":413961147}}},{"delta":{"node-LatLon":{"lon":-1101702710,"lat":413993844}}},{"delta":{"node-LatLon":{"lon":-1101638962,"lat":414026618}}},{"delta":{"node-LatLon":{"lon":-1101574959,"lat":414059103}}},{"delta":{"node-LatLon":{"lon":-1101503795,"lat":414079486}}},{"delta":{"node-LatLon":{"lon":-1101430050,"lat":414094635}}},{"delta":{"node-LatLon":{"lon":-1101364010,"lat":414123142}}},{"delta":{"node-LatLon":{"lon":-1101315879,"lat":414167652}}},{"delta":{"node-LatLon":{"lon":-1101285137,"lat":414220512}}},{"delta":{"node-LatLon":{"lon":-1101240865,"lat":414267227}}},{"delta":{"node-LatLon":{"lon":-1101177309,"lat":414298942}}},{"delta":{"node-LatLon":{"lon":-1101107194,"lat":414323150}}},{"delta":{"node-LatLon":{"lon":-1101071949,"lat":414335378}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111000000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413560362,"long":-1103396637}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1024004,"speed":23.76,"longitude":-105.0477462},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":48,"serialNumber":15477,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.453Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31329,"packetID":"0000000000000D30E2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415444795,"long":-1099085600},"name":"westbound_I80_53.31_66.17_SAT-4E185B11_RC_GRAI80WLYMD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1099104884,"lat":415443688}}},{"delta":{"node-LatLon":{"lon":-1099142907,"lat":415438499}}},{"delta":{"node-LatLon":{"lon":-1099213633,"lat":415416960}}},{"delta":{"node-LatLon":{"lon":-1099277798,"lat":415385610}}},{"delta":{"node-LatLon":{"lon":-1099341920,"lat":415353771}}},{"delta":{"node-LatLon":{"lon":-1099406318,"lat":415321821}}},{"delta":{"node-LatLon":{"lon":-1099470693,"lat":415289849}}},{"delta":{"node-LatLon":{"lon":-1099535924,"lat":415257482}}},{"delta":{"node-LatLon":{"lon":-1099601115,"lat":415225072}}},{"delta":{"node-LatLon":{"lon":-1099665873,"lat":415192909}}},{"delta":{"node-LatLon":{"lon":-1099730154,"lat":415160943}}},{"delta":{"node-LatLon":{"lon":-1099794423,"lat":415128966}}},{"delta":{"node-LatLon":{"lon":-1099858611,"lat":415097082}}},{"delta":{"node-LatLon":{"lon":-1099922767,"lat":415065163}}},{"delta":{"node-LatLon":{"lon":-1099986894,"lat":415033282}}},{"delta":{"node-LatLon":{"lon":-1100050552,"lat":415000958}}},{"delta":{"node-LatLon":{"lon":-1100107537,"lat":414962342}}},{"delta":{"node-LatLon":{"lon":-1100159317,"lat":414919942}}},{"delta":{"node-LatLon":{"lon":-1100210275,"lat":414877000}}},{"delta":{"node-LatLon":{"lon":-1100258455,"lat":414831964}}},{"delta":{"node-LatLon":{"lon":-1100306816,"lat":414786740}}},{"delta":{"node-LatLon":{"lon":-1100355125,"lat":414741487}}},{"delta":{"node-LatLon":{"lon":-1100406269,"lat":414698457}}},{"delta":{"node-LatLon":{"lon":-1100466077,"lat":414662270}}},{"delta":{"node-LatLon":{"lon":-1100529550,"lat":414626554}}},{"delta":{"node-LatLon":{"lon":-1100594995,"lat":414589736}}},{"delta":{"node-LatLon":{"lon":-1100660445,"lat":414552926}}},{"delta":{"node-LatLon":{"lon":-1100720966,"lat":414518811}}},{"delta":{"node-LatLon":{"lon":-1100781507,"lat":414484719}}},{"delta":{"node-LatLon":{"lon":-1100843008,"lat":414450048}}},{"delta":{"node-LatLon":{"lon":-1100905513,"lat":414414842}}},{"delta":{"node-LatLon":{"lon":-1100968090,"lat":414379712}}},{"delta":{"node-LatLon":{"lon":-1101034065,"lat":414350776}}},{"delta":{"node-LatLon":{"lon":-1101086165,"lat":414332737}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001110000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415444795,"long":-1099085600}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31329}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":46,"serialNumber":15475,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000AA646","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413135480,"long":-1105064011},"name":"westbound_I80_18.29_30.4_SAT-4E8C2D1C_RC_EVANI80ELYM2D","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1105081636,"lat":413129581}}},{"delta":{"node-LatLon":{"lon":-1105152429,"lat":413106493}}},{"delta":{"node-LatLon":{"lon":-1105222681,"lat":413083154}}},{"delta":{"node-LatLon":{"lon":-1105293041,"lat":413060007}}},{"delta":{"node-LatLon":{"lon":-1105365675,"lat":413036053}}},{"delta":{"node-LatLon":{"lon":-1105440576,"lat":413011281}}},{"delta":{"node-LatLon":{"lon":-1105515498,"lat":412986550}}},{"delta":{"node-LatLon":{"lon":-1105587007,"lat":412974643}}},{"delta":{"node-LatLon":{"lon":-1105660608,"lat":412975574}}},{"delta":{"node-LatLon":{"lon":-1105734210,"lat":412976799}}},{"delta":{"node-LatLon":{"lon":-1105807811,"lat":412978023}}},{"delta":{"node-LatLon":{"lon":-1105881411,"lat":412979276}}},{"delta":{"node-LatLon":{"lon":-1105958106,"lat":412980598}}},{"delta":{"node-LatLon":{"lon":-1106034803,"lat":412981835}}},{"delta":{"node-LatLon":{"lon":-1106111006,"lat":412983091}}},{"delta":{"node-LatLon":{"lon":-1106186716,"lat":412984304}}},{"delta":{"node-LatLon":{"lon":-1106262425,"lat":412985553}}},{"delta":{"node-LatLon":{"lon":-1106340719,"lat":412986812}}},{"delta":{"node-LatLon":{"lon":-1106419013,"lat":412988052}}},{"delta":{"node-LatLon":{"lon":-1106496051,"lat":412989281}}},{"delta":{"node-LatLon":{"lon":-1106571818,"lat":412990824}}},{"delta":{"node-LatLon":{"lon":-1106647599,"lat":412992029}}},{"delta":{"node-LatLon":{"lon":-1106726085,"lat":412993268}}},{"delta":{"node-LatLon":{"lon":-1106803345,"lat":412986953}}},{"delta":{"node-LatLon":{"lon":-1106867780,"lat":412955347}}},{"delta":{"node-LatLon":{"lon":-1106940824,"lat":412955290}}},{"delta":{"node-LatLon":{"lon":-1107004030,"lat":412986369}}},{"delta":{"node-LatLon":{"lon":-1107075211,"lat":413008691}}},{"delta":{"node-LatLon":{"lon":-1107146451,"lat":413030911}}},{"delta":{"node-LatLon":{"lon":-1107217304,"lat":413052985}}},{"delta":{"node-LatLon":{"lon":-1107287759,"lat":413074934}}},{"delta":{"node-LatLon":{"lon":-1107323024,"lat":413085837}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413135480,"long":-1105064011}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":45,"serialNumber":15474,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000103B16","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413088220,"long":-1107346769},"name":"eastbound_I80_18.29_30.4_SAT-1BB0E1D9_RC_EVANI80ELYM2I","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1107327853,"lat":413085207}}},{"delta":{"node-LatLon":{"lon":-1107291892,"lat":413074355}}},{"delta":{"node-LatLon":{"lon":-1107220291,"lat":413052030}}},{"delta":{"node-LatLon":{"lon":-1107148980,"lat":413029795}}},{"delta":{"node-LatLon":{"lon":-1107078119,"lat":413007369}}},{"delta":{"node-LatLon":{"lon":-1107007132,"lat":412985172}}},{"delta":{"node-LatLon":{"lon":-1106941741,"lat":412953720}}},{"delta":{"node-LatLon":{"lon":-1106866866,"lat":412953036}}},{"delta":{"node-LatLon":{"lon":-1106802203,"lat":412985015}}},{"delta":{"node-LatLon":{"lon":-1106726168,"lat":412991195}}},{"delta":{"node-LatLon":{"lon":-1106648917,"lat":412989976}}},{"delta":{"node-LatLon":{"lon":-1106573197,"lat":412988796}}},{"delta":{"node-LatLon":{"lon":-1106497477,"lat":412987600}}},{"delta":{"node-LatLon":{"lon":-1106420644,"lat":412986371}}},{"delta":{"node-LatLon":{"lon":-1106342697,"lat":412985100}}},{"delta":{"node-LatLon":{"lon":-1106264749,"lat":412983842}}},{"delta":{"node-LatLon":{"lon":-1106189077,"lat":412982627}}},{"delta":{"node-LatLon":{"lon":-1106113405,"lat":412981388}}},{"delta":{"node-LatLon":{"lon":-1106037230,"lat":412980142}}},{"delta":{"node-LatLon":{"lon":-1105960566,"lat":412978554}}},{"delta":{"node-LatLon":{"lon":-1105883887,"lat":412977263}}},{"delta":{"node-LatLon":{"lon":-1105807259,"lat":412976192}}},{"delta":{"node-LatLon":{"lon":-1105730649,"lat":412974694}}},{"delta":{"node-LatLon":{"lon":-1105656816,"lat":412973443}}},{"delta":{"node-LatLon":{"lon":-1105585775,"lat":412972496}}},{"delta":{"node-LatLon":{"lon":-1105516502,"lat":412983227}}},{"delta":{"node-LatLon":{"lon":-1105441920,"lat":413008048}}},{"delta":{"node-LatLon":{"lon":-1105367237,"lat":413032710}}},{"delta":{"node-LatLon":{"lon":-1105294291,"lat":413056763}}},{"delta":{"node-LatLon":{"lon":-1105223123,"lat":413080276}}},{"delta":{"node-LatLon":{"lon":-1105151956,"lat":413103795}}},{"delta":{"node-LatLon":{"lon":-1105081780,"lat":413126737}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413088220,"long":-1107346769}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023962,"speed":23.76,"longitude":-105.047774},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":44,"serialNumber":15473,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.998Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"0000000000000E3CF2","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":413074934,"long":-1107287759},"name":"westbound_I80_6.26_18.29_SAT-6167B0AE_RC_EVANI80ELYMD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1107305366,"lat":413080434}}},{"delta":{"node-LatLon":{"lon":-1107360431,"lat":413090250}}},{"delta":{"node-LatLon":{"lon":-1107435889,"lat":413072542}}},{"delta":{"node-LatLon":{"lon":-1107510137,"lat":413051412}}},{"delta":{"node-LatLon":{"lon":-1107583237,"lat":413030611}}},{"delta":{"node-LatLon":{"lon":-1107651303,"lat":413004057}}},{"delta":{"node-LatLon":{"lon":-1107715511,"lat":412972132}}},{"delta":{"node-LatLon":{"lon":-1107779433,"lat":412939683}}},{"delta":{"node-LatLon":{"lon":-1107834761,"lat":412899298}}},{"delta":{"node-LatLon":{"lon":-1107888585,"lat":412858118}}},{"delta":{"node-LatLon":{"lon":-1107942218,"lat":412817220}}},{"delta":{"node-LatLon":{"lon":-1107995791,"lat":412776279}}},{"delta":{"node-LatLon":{"lon":-1108052203,"lat":412738880}}},{"delta":{"node-LatLon":{"lon":-1108125567,"lat":412730945}}},{"delta":{"node-LatLon":{"lon":-1108200890,"lat":412730979}}},{"delta":{"node-LatLon":{"lon":-1108269016,"lat":412705671}}},{"delta":{"node-LatLon":{"lon":-1108336945,"lat":412680037}}},{"delta":{"node-LatLon":{"lon":-1108412418,"lat":412681664}}},{"delta":{"node-LatLon":{"lon":-1108481367,"lat":412706514}}},{"delta":{"node-LatLon":{"lon":-1108552780,"lat":412726456}}},{"delta":{"node-LatLon":{"lon":-1108625458,"lat":412710792}}},{"delta":{"node-LatLon":{"lon":-1108688492,"lat":412677244}}},{"delta":{"node-LatLon":{"lon":-1108755794,"lat":412649329}}},{"delta":{"node-LatLon":{"lon":-1108828743,"lat":412631226}}},{"delta":{"node-LatLon":{"lon":-1108904794,"lat":412623516}}},{"delta":{"node-LatLon":{"lon":-1108981375,"lat":412626474}}},{"delta":{"node-LatLon":{"lon":-1109056338,"lat":412638897}}},{"delta":{"node-LatLon":{"lon":-1109130675,"lat":412652858}}},{"delta":{"node-LatLon":{"lon":-1109205469,"lat":412665291}}},{"delta":{"node-LatLon":{"lon":-1109280079,"lat":412673471}}},{"delta":{"node-LatLon":{"lon":-1109353719,"lat":412680146}}},{"delta":{"node-LatLon":{"lon":-1109390798,"lat":412680579}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000001111100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":413074934,"long":-1107287759}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023921,"speed":23.64,"longitude":-105.0478016},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":43,"serialNumber":15472,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31337,"packetID":"000000000000085B12","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412678295,"long":-1109403156},"name":"eastbound_I80_6.26_18.29_SAT-5481DCC7_RC_EVANI80ELYMI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1109383397,"lat":412678737}}},{"delta":{"node-LatLon":{"lon":-1109363631,"lat":412678500}}},{"delta":{"node-LatLon":{"lon":-1109285083,"lat":412671839}}},{"delta":{"node-LatLon":{"lon":-1109208218,"lat":412662718}}},{"delta":{"node-LatLon":{"lon":-1109133790,"lat":412649197}}},{"delta":{"node-LatLon":{"lon":-1109059500,"lat":412635242}}},{"delta":{"node-LatLon":{"lon":-1108983731,"lat":412622770}}},{"delta":{"node-LatLon":{"lon":-1108906400,"lat":412619640}}},{"delta":{"node-LatLon":{"lon":-1108829878,"lat":412627699}}},{"delta":{"node-LatLon":{"lon":-1108756816,"lat":412646172}}},{"delta":{"node-LatLon":{"lon":-1108689511,"lat":412674500}}},{"delta":{"node-LatLon":{"lon":-1108627647,"lat":412707502}}},{"delta":{"node-LatLon":{"lon":-1108557015,"lat":412724866}}},{"delta":{"node-LatLon":{"lon":-1108485391,"lat":412706101}}},{"delta":{"node-LatLon":{"lon":-1108415692,"lat":412680645}}},{"delta":{"node-LatLon":{"lon":-1108339283,"lat":412677822}}},{"delta":{"node-LatLon":{"lon":-1108270801,"lat":412702792}}},{"delta":{"node-LatLon":{"lon":-1108202724,"lat":412728468}}},{"delta":{"node-LatLon":{"lon":-1108127111,"lat":412729008}}},{"delta":{"node-LatLon":{"lon":-1108052987,"lat":412735898}}},{"delta":{"node-LatLon":{"lon":-1107995597,"lat":412772983}}},{"delta":{"node-LatLon":{"lon":-1107941620,"lat":412814258}}},{"delta":{"node-LatLon":{"lon":-1107887900,"lat":412855724}}},{"delta":{"node-LatLon":{"lon":-1107834045,"lat":412896917}}},{"delta":{"node-LatLon":{"lon":-1107779426,"lat":412937317}}},{"delta":{"node-LatLon":{"lon":-1107716124,"lat":412969726}}},{"delta":{"node-LatLon":{"lon":-1107651938,"lat":413001633}}},{"delta":{"node-LatLon":{"lon":-1107584096,"lat":413028452}}},{"delta":{"node-LatLon":{"lon":-1107511903,"lat":413049025}}},{"delta":{"node-LatLon":{"lon":-1107439402,"lat":413069631}}},{"delta":{"node-LatLon":{"lon":-1107366103,"lat":413088130}}},{"delta":{"node-LatLon":{"lon":-1107309808,"lat":413079907}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0111110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412678295,"long":-1109403156}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5907}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31337}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023921,"speed":23.64,"longitude":-105.0478016},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":42,"serialNumber":15471,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31461,"packetID":"00000000000002B464","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412378541,"long":-1054372542},"name":"westbound_I80_317.45_323.05_SAT-DBAB5858_RC_LARI80ECHEYD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}},{"delta":{"node-LatLon":{"lon":-1054421149,"lat":412472313}}},{"delta":{"node-LatLon":{"lon":-1054429340,"lat":412485351}}},{"delta":{"node-LatLon":{"lon":-1054437555,"lat":412498379}}},{"delta":{"node-LatLon":{"lon":-1054445744,"lat":412511417}}},{"delta":{"node-LatLon":{"lon":-1054453974,"lat":412524441}}},{"delta":{"node-LatLon":{"lon":-1054463289,"lat":412537025}}},{"delta":{"node-LatLon":{"lon":-1054475122,"lat":412548474}}},{"delta":{"node-LatLon":{"lon":-1054489160,"lat":412558405}}},{"delta":{"node-LatLon":{"lon":-1054504069,"lat":412567600}}},{"delta":{"node-LatLon":{"lon":-1054519000,"lat":412576776}}},{"delta":{"node-LatLon":{"lon":-1054533896,"lat":412585985}}},{"delta":{"node-LatLon":{"lon":-1054548833,"lat":412595156}}},{"delta":{"node-LatLon":{"lon":-1054563820,"lat":412604280}}},{"delta":{"node-LatLon":{"lon":-1054579779,"lat":412612388}}},{"delta":{"node-LatLon":{"lon":-1054597055,"lat":412618777}}},{"delta":{"node-LatLon":{"lon":-1054615114,"lat":412623812}}},{"delta":{"node-LatLon":{"lon":-1054632271,"lat":412629637}}},{"delta":{"node-LatLon":{"lon":-1054647306,"lat":412638180}}},{"delta":{"node-LatLon":{"lon":-1054662004,"lat":412647078}}},{"delta":{"node-LatLon":{"lon":-1054678467,"lat":412653902}}},{"delta":{"node-LatLon":{"lon":-1054696868,"lat":412656761}}},{"delta":{"node-LatLon":{"lon":-1054715678,"lat":412657581}}},{"delta":{"node-LatLon":{"lon":-1054734355,"lat":412659287}}},{"delta":{"node-LatLon":{"lon":-1054751683,"lat":412664718}}},{"delta":{"node-LatLon":{"lon":-1054765976,"lat":412673917}}},{"delta":{"node-LatLon":{"lon":-1054778503,"lat":412684544}}},{"delta":{"node-LatLon":{"lon":-1054791379,"lat":412695492}}},{"delta":{"node-LatLon":{"lon":-1054804278,"lat":412706425}}},{"delta":{"node-LatLon":{"lon":-1054818479,"lat":412716349}}},{"delta":{"node-LatLon":{"lon":-1054835859,"lat":412722690}}},{"delta":{"node-LatLon":{"lon":-1054854996,"lat":412724695}}},{"delta":{"node-LatLon":{"lon":-1054874196,"lat":412722759}}},{"delta":{"node-LatLon":{"lon":-1054893260,"lat":412720064}}},{"delta":{"node-LatLon":{"lon":-1054912492,"lat":412718274}}},{"delta":{"node-LatLon":{"lon":-1054931875,"lat":412718613}}},{"delta":{"node-LatLon":{"lon":-1054951253,"lat":412719209}}},{"delta":{"node-LatLon":{"lon":-1054969662,"lat":412719789}}},{"delta":{"node-LatLon":{"lon":-1054987987,"lat":412721117}}},{"delta":{"node-LatLon":{"lon":-1055005745,"lat":412724757}}},{"delta":{"node-LatLon":{"lon":-1055022420,"lat":412730636}}},{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412378541,"long":-1054372542}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31461}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6,"latitude":41.1023878,"speed":23.64,"longitude":-105.0478293},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":41,"serialNumber":15470,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31461,"packetID":"0000000000000939DD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412846200,"long":-1055207674},"name":"eastbound_I80_317.45_323.05_SAT-85B2D861_RC_LARI80ECHEYI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055196465,"lat":412834401}}},{"delta":{"node-LatLon":{"lon":-1055185238,"lat":412822611}}},{"delta":{"node-LatLon":{"lon":-1055174028,"lat":412810812}}},{"delta":{"node-LatLon":{"lon":-1055162838,"lat":412799002}}},{"delta":{"node-LatLon":{"lon":-1055151564,"lat":412787238}}},{"delta":{"node-LatLon":{"lon":-1055139485,"lat":412775945}}},{"delta":{"node-LatLon":{"lon":-1055126153,"lat":412765484}}},{"delta":{"node-LatLon":{"lon":-1055111710,"lat":412756134}}},{"delta":{"node-LatLon":{"lon":-1055096204,"lat":412747808}}},{"delta":{"node-LatLon":{"lon":-1055080126,"lat":412740115}}},{"delta":{"node-LatLon":{"lon":-1055063926,"lat":412732570}}},{"delta":{"node-LatLon":{"lon":-1055046853,"lat":412726244}}},{"delta":{"node-LatLon":{"lon":-1055028777,"lat":412721773}}},{"delta":{"node-LatLon":{"lon":-1055009981,"lat":412719587}}},{"delta":{"node-LatLon":{"lon":-1054990989,"lat":412718648}}},{"delta":{"node-LatLon":{"lon":-1054972006,"lat":412717639}}},{"delta":{"node-LatLon":{"lon":-1054953009,"lat":412716759}}},{"delta":{"node-LatLon":{"lon":-1054934016,"lat":412716179}}},{"delta":{"node-LatLon":{"lon":-1054915016,"lat":412715870}}},{"delta":{"node-LatLon":{"lon":-1054896123,"lat":412717322}}},{"delta":{"node-LatLon":{"lon":-1054877421,"lat":412719892}}},{"delta":{"node-LatLon":{"lon":-1054858665,"lat":412722173}}},{"delta":{"node-LatLon":{"lon":-1054839790,"lat":412721101}}},{"delta":{"node-LatLon":{"lon":-1054822378,"lat":412715508}}},{"delta":{"node-LatLon":{"lon":-1054808075,"lat":412706122}}},{"delta":{"node-LatLon":{"lon":-1054795466,"lat":412695384}}},{"delta":{"node-LatLon":{"lon":-1054782861,"lat":412684644}}},{"delta":{"node-LatLon":{"lon":-1054770097,"lat":412673836}}},{"delta":{"node-LatLon":{"lon":-1054756003,"lat":412664064}}},{"delta":{"node-LatLon":{"lon":-1054738855,"lat":412657720}}},{"delta":{"node-LatLon":{"lon":-1054719971,"lat":412655405}}},{"delta":{"node-LatLon":{"lon":-1054700821,"lat":412654615}}},{"delta":{"node-LatLon":{"lon":-1054681944,"lat":412652284}}},{"delta":{"node-LatLon":{"lon":-1054664843,"lat":412645844}}},{"delta":{"node-LatLon":{"lon":-1054649671,"lat":412637001}}},{"delta":{"node-LatLon":{"lon":-1054634409,"lat":412628251}}},{"delta":{"node-LatLon":{"lon":-1054617259,"lat":412621852}}},{"delta":{"node-LatLon":{"lon":-1054599367,"lat":412616899}}},{"delta":{"node-LatLon":{"lon":-1054582192,"lat":412610689}}},{"delta":{"node-LatLon":{"lon":-1054566302,"lat":412602767}}},{"delta":{"node-LatLon":{"lon":-1054551500,"lat":412593707}}},{"delta":{"node-LatLon":{"lon":-1054536736,"lat":412584610}}},{"delta":{"node-LatLon":{"lon":-1054521939,"lat":412575543}}},{"delta":{"node-LatLon":{"lon":-1054507197,"lat":412566427}}},{"delta":{"node-LatLon":{"lon":-1054492428,"lat":412557334}}},{"delta":{"node-LatLon":{"lon":-1054478373,"lat":412547636}}},{"delta":{"node-LatLon":{"lon":-1054466482,"lat":412536415}}},{"delta":{"node-LatLon":{"lon":-1054457123,"lat":412523979}}},{"delta":{"node-LatLon":{"lon":-1054448979,"lat":412511051}}},{"delta":{"node-LatLon":{"lon":-1054440857,"lat":412498114}}},{"delta":{"node-LatLon":{"lon":-1054432727,"lat":412485180}}},{"delta":{"node-LatLon":{"lon":-1054424622,"lat":412472238}}},{"delta":{"node-LatLon":{"lon":-1054416471,"lat":412459312}}},{"delta":{"node-LatLon":{"lon":-1054408332,"lat":412446382}}},{"delta":{"node-LatLon":{"lon":-1054400231,"lat":412433438}}},{"delta":{"node-LatLon":{"lon":-1054392109,"lat":412420501}}},{"delta":{"node-LatLon":{"lon":-1054384744,"lat":412407315}}},{"delta":{"node-LatLon":{"lon":-1054379237,"lat":412393551}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412846200,"long":-1055207674}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5906}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31461}},"msgCnt":12}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023793,"speed":23.56,"longitude":-105.0478845},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":40,"serialNumber":15469,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:09.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31306,"packetID":"0000000000000936E7","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417414634,"long":-1068269969},"name":"westbound_I80_221.2_235.23_SAT-09D8678A_RC_RAWI80ELARD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068289321,"lat":417415359}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}},{"delta":{"node-LatLon":{"lon":-1068385974,"lat":417418859}}},{"delta":{"node-LatLon":{"lon":-1068463156,"lat":417421689}}},{"delta":{"node-LatLon":{"lon":-1068540338,"lat":417424515}}},{"delta":{"node-LatLon":{"lon":-1068617852,"lat":417427395}}},{"delta":{"node-LatLon":{"lon":-1068695369,"lat":417430231}}},{"delta":{"node-LatLon":{"lon":-1068772890,"lat":417433050}}},{"delta":{"node-LatLon":{"lon":-1068850417,"lat":417435830}}},{"delta":{"node-LatLon":{"lon":-1068927943,"lat":417438632}}},{"delta":{"node-LatLon":{"lon":-1069005025,"lat":417441424}}},{"delta":{"node-LatLon":{"lon":-1069082106,"lat":417444219}}},{"delta":{"node-LatLon":{"lon":-1069159408,"lat":417446974}}},{"delta":{"node-LatLon":{"lon":-1069236759,"lat":417451306}}},{"delta":{"node-LatLon":{"lon":-1069312011,"lat":417465173}}},{"delta":{"node-LatLon":{"lon":-1069385103,"lat":417484568}}},{"delta":{"node-LatLon":{"lon":-1069458135,"lat":417504094}}},{"delta":{"node-LatLon":{"lon":-1069530060,"lat":417523167}}},{"delta":{"node-LatLon":{"lon":-1069600849,"lat":417541844}}},{"delta":{"node-LatLon":{"lon":-1069673525,"lat":417555795}}},{"delta":{"node-LatLon":{"lon":-1069748966,"lat":417568966}}},{"delta":{"node-LatLon":{"lon":-1069824418,"lat":417582109}}},{"delta":{"node-LatLon":{"lon":-1069899351,"lat":417595155}}},{"delta":{"node-LatLon":{"lon":-1069973766,"lat":417608100}}},{"delta":{"node-LatLon":{"lon":-1070048170,"lat":417621086}}},{"delta":{"node-LatLon":{"lon":-1070123773,"lat":417634264}}},{"delta":{"node-LatLon":{"lon":-1070199399,"lat":417647374}}},{"delta":{"node-LatLon":{"lon":-1070274965,"lat":417660512}}},{"delta":{"node-LatLon":{"lon":-1070350472,"lat":417673678}}},{"delta":{"node-LatLon":{"lon":-1070425989,"lat":417686813}}},{"delta":{"node-LatLon":{"lon":-1070501711,"lat":417699947}}},{"delta":{"node-LatLon":{"lon":-1070577425,"lat":417713109}}},{"delta":{"node-LatLon":{"lon":-1070653637,"lat":417726293}}},{"delta":{"node-LatLon":{"lon":-1070730992,"lat":417736504}}},{"delta":{"node-LatLon":{"lon":-1070808409,"lat":417727589}}},{"delta":{"node-LatLon":{"lon":-1070884161,"lat":417718392}}},{"delta":{"node-LatLon":{"lon":-1070959940,"lat":417729715}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417414634,"long":-1068269969}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31306}},"msgCnt":32}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023793,"speed":23.56,"longitude":-105.0478845},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":39,"serialNumber":15468,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31306,"packetID":"00000000000009698C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417730521,"long":-1070980675},"name":"eastbound_I80_221.2_235.23_SAT-BA88D691_RC_RAWI80ELARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1070961677,"lat":417727641}}},{"delta":{"node-LatLon":{"lon":-1070885649,"lat":417716362}}},{"delta":{"node-LatLon":{"lon":-1070809626,"lat":417725169}}},{"delta":{"node-LatLon":{"lon":-1070732756,"lat":417733042}}},{"delta":{"node-LatLon":{"lon":-1070656229,"lat":417722191}}},{"delta":{"node-LatLon":{"lon":-1070580490,"lat":417709023}}},{"delta":{"node-LatLon":{"lon":-1070504992,"lat":417695900}}},{"delta":{"node-LatLon":{"lon":-1070429493,"lat":417682786}}},{"delta":{"node-LatLon":{"lon":-1070354047,"lat":417669673}}},{"delta":{"node-LatLon":{"lon":-1070278596,"lat":417656581}}},{"delta":{"node-LatLon":{"lon":-1070202954,"lat":417643413}}},{"delta":{"node-LatLon":{"lon":-1070127097,"lat":417630244}}},{"delta":{"node-LatLon":{"lon":-1070051256,"lat":417617028}}},{"delta":{"node-LatLon":{"lon":-1069975759,"lat":417603852}}},{"delta":{"node-LatLon":{"lon":-1069900250,"lat":417590719}}},{"delta":{"node-LatLon":{"lon":-1069825529,"lat":417577695}}},{"delta":{"node-LatLon":{"lon":-1069751604,"lat":417564757}}},{"delta":{"node-LatLon":{"lon":-1069677665,"lat":417551870}}},{"delta":{"node-LatLon":{"lon":-1069603910,"lat":417538967}}},{"delta":{"node-LatLon":{"lon":-1069531945,"lat":417521380}}},{"delta":{"node-LatLon":{"lon":-1069460002,"lat":417502274}}},{"delta":{"node-LatLon":{"lon":-1069387530,"lat":417482961}}},{"delta":{"node-LatLon":{"lon":-1069315049,"lat":417463671}}},{"delta":{"node-LatLon":{"lon":-1069240161,"lat":417448143}}},{"delta":{"node-LatLon":{"lon":-1069162781,"lat":417442613}}},{"delta":{"node-LatLon":{"lon":-1069085198,"lat":417439823}}},{"delta":{"node-LatLon":{"lon":-1069007744,"lat":417437041}}},{"delta":{"node-LatLon":{"lon":-1068930291,"lat":417434237}}},{"delta":{"node-LatLon":{"lon":-1068853004,"lat":417431463}}},{"delta":{"node-LatLon":{"lon":-1068775721,"lat":417428637}}},{"delta":{"node-LatLon":{"lon":-1068698384,"lat":417425830}}},{"delta":{"node-LatLon":{"lon":-1068620993,"lat":417423054}}},{"delta":{"node-LatLon":{"lon":-1068543604,"lat":417420239}}},{"delta":{"node-LatLon":{"lon":-1068465827,"lat":417417448}}},{"delta":{"node-LatLon":{"lon":-1068388058,"lat":417414571}}},{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068291290,"lat":417411033}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417730521,"long":-1070980675}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31306}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023754,"speed":23.44,"longitude":-105.047912},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":38,"serialNumber":15467,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.951Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"0000000000000CAD04","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417236030,"long":-1064577050},"name":"westbound_I80_235.23_255.6_SAT-5249C81B_RC_EMI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}},{"delta":{"node-LatLon":{"lon":-1064663938,"lat":417268988}}},{"delta":{"node-LatLon":{"lon":-1064732992,"lat":417295169}}},{"delta":{"node-LatLon":{"lon":-1064801593,"lat":417321158}}},{"delta":{"node-LatLon":{"lon":-1064868982,"lat":417348724}}},{"delta":{"node-LatLon":{"lon":-1064918112,"lat":417392970}}},{"delta":{"node-LatLon":{"lon":-1064954285,"lat":417444108}}},{"delta":{"node-LatLon":{"lon":-1065013176,"lat":417481407}}},{"delta":{"node-LatLon":{"lon":-1065076232,"lat":417514937}}},{"delta":{"node-LatLon":{"lon":-1065143647,"lat":417541998}}},{"delta":{"node-LatLon":{"lon":-1065216141,"lat":417525688}}},{"delta":{"node-LatLon":{"lon":-1065286224,"lat":417501265}}},{"delta":{"node-LatLon":{"lon":-1065362113,"lat":417489852}}},{"delta":{"node-LatLon":{"lon":-1065436335,"lat":417474443}}},{"delta":{"node-LatLon":{"lon":-1065509545,"lat":417456289}}},{"delta":{"node-LatLon":{"lon":-1065583202,"lat":417438150}}},{"delta":{"node-LatLon":{"lon":-1065656809,"lat":417419903}}},{"delta":{"node-LatLon":{"lon":-1065731883,"lat":417405563}}},{"delta":{"node-LatLon":{"lon":-1065807502,"lat":417392751}}},{"delta":{"node-LatLon":{"lon":-1065883116,"lat":417379926}}},{"delta":{"node-LatLon":{"lon":-1065957863,"lat":417367400}}},{"delta":{"node-LatLon":{"lon":-1066034015,"lat":417367499}}},{"delta":{"node-LatLon":{"lon":-1066107964,"lat":417383273}}},{"delta":{"node-LatLon":{"lon":-1066182713,"lat":417397479}}},{"delta":{"node-LatLon":{"lon":-1066259373,"lat":417393785}}},{"delta":{"node-LatLon":{"lon":-1066332961,"lat":417375298}}},{"delta":{"node-LatLon":{"lon":-1066406270,"lat":417356150}}},{"delta":{"node-LatLon":{"lon":-1066479386,"lat":417336915}}},{"delta":{"node-LatLon":{"lon":-1066552888,"lat":417319016}}},{"delta":{"node-LatLon":{"lon":-1066629919,"lat":417314788}}},{"delta":{"node-LatLon":{"lon":-1066707699,"lat":417312949}}},{"delta":{"node-LatLon":{"lon":-1066785479,"lat":417311107}}},{"delta":{"node-LatLon":{"lon":-1066862945,"lat":417309275}}},{"delta":{"node-LatLon":{"lon":-1066940095,"lat":417307413}}},{"delta":{"node-LatLon":{"lon":-1067017196,"lat":417307583}}},{"delta":{"node-LatLon":{"lon":-1067093337,"lat":417317382}}},{"delta":{"node-LatLon":{"lon":-1067169430,"lat":417327402}}},{"delta":{"node-LatLon":{"lon":-1067245652,"lat":417337364}}},{"delta":{"node-LatLon":{"lon":-1067321980,"lat":417347366}}},{"delta":{"node-LatLon":{"lon":-1067398306,"lat":417357382}}},{"delta":{"node-LatLon":{"lon":-1067473287,"lat":417371223}}},{"delta":{"node-LatLon":{"lon":-1067545644,"lat":417391873}}},{"delta":{"node-LatLon":{"lon":-1067618034,"lat":417412485}}},{"delta":{"node-LatLon":{"lon":-1067691111,"lat":417431502}}},{"delta":{"node-LatLon":{"lon":-1067768403,"lat":417431260}}},{"delta":{"node-LatLon":{"lon":-1067845690,"lat":417428509}}},{"delta":{"node-LatLon":{"lon":-1067922977,"lat":417425763}}},{"delta":{"node-LatLon":{"lon":-1068000058,"lat":417422940}}},{"delta":{"node-LatLon":{"lon":-1068076949,"lat":417420295}}},{"delta":{"node-LatLon":{"lon":-1068153829,"lat":417417471}}},{"delta":{"node-LatLon":{"lon":-1068231245,"lat":417414693}}},{"delta":{"node-LatLon":{"lon":-1068308673,"lat":417416093}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000111110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417236030,"long":-1064577050}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.6625,"latitude":41.1023754,"speed":23.44,"longitude":-105.047912},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":37,"serialNumber":15466,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.853Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"0000000000000B72CD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417412478,"long":-1068329876},"name":"eastbound_I80_235.23_255.6_SAT-BC6CCC19_RC_EMI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1068310584,"lat":417411739}}},{"delta":{"node-LatLon":{"lon":-1068233386,"lat":417410283}}},{"delta":{"node-LatLon":{"lon":-1068156206,"lat":417413060}}},{"delta":{"node-LatLon":{"lon":-1068078777,"lat":417415820}}},{"delta":{"node-LatLon":{"lon":-1068001349,"lat":417418584}}},{"delta":{"node-LatLon":{"lon":-1067924043,"lat":417421374}}},{"delta":{"node-LatLon":{"lon":-1067846854,"lat":417424119}}},{"delta":{"node-LatLon":{"lon":-1067769664,"lat":417426862}}},{"delta":{"node-LatLon":{"lon":-1067693191,"lat":417427429}}},{"delta":{"node-LatLon":{"lon":-1067620890,"lat":417408658}}},{"delta":{"node-LatLon":{"lon":-1067548859,"lat":417388122}}},{"delta":{"node-LatLon":{"lon":-1067476428,"lat":417367444}}},{"delta":{"node-LatLon":{"lon":-1067401438,"lat":417353366}}},{"delta":{"node-LatLon":{"lon":-1067324763,"lat":417343330}}},{"delta":{"node-LatLon":{"lon":-1067248094,"lat":417333277}}},{"delta":{"node-LatLon":{"lon":-1067171506,"lat":417323258}}},{"delta":{"node-LatLon":{"lon":-1067095014,"lat":417313213}}},{"delta":{"node-LatLon":{"lon":-1067018343,"lat":417304140}}},{"delta":{"node-LatLon":{"lon":-1066941341,"lat":417305018}}},{"delta":{"node-LatLon":{"lon":-1066864327,"lat":417306535}}},{"delta":{"node-LatLon":{"lon":-1066786982,"lat":417308392}}},{"delta":{"node-LatLon":{"lon":-1066709294,"lat":417310231}}},{"delta":{"node-LatLon":{"lon":-1066631604,"lat":417312052}}},{"delta":{"node-LatLon":{"lon":-1066553905,"lat":417315567}}},{"delta":{"node-LatLon":{"lon":-1066479234,"lat":417331977}}},{"delta":{"node-LatLon":{"lon":-1066405938,"lat":417350968}}},{"delta":{"node-LatLon":{"lon":-1066333222,"lat":417370336}}},{"delta":{"node-LatLon":{"lon":-1066260210,"lat":417389047}}},{"delta":{"node-LatLon":{"lon":-1066185059,"lat":417393215}}},{"delta":{"node-LatLon":{"lon":-1066111705,"lat":417379368}}},{"delta":{"node-LatLon":{"lon":-1066037468,"lat":417363405}}},{"delta":{"node-LatLon":{"lon":-1065959182,"lat":417362605}}},{"delta":{"node-LatLon":{"lon":-1065882330,"lat":417375426}}},{"delta":{"node-LatLon":{"lon":-1065806758,"lat":417388216}}},{"delta":{"node-LatLon":{"lon":-1065731194,"lat":417401042}}},{"delta":{"node-LatLon":{"lon":-1065656118,"lat":417415246}}},{"delta":{"node-LatLon":{"lon":-1065582542,"lat":417433443}}},{"delta":{"node-LatLon":{"lon":-1065508992,"lat":417451702}}},{"delta":{"node-LatLon":{"lon":-1065434680,"lat":417470091}}},{"delta":{"node-LatLon":{"lon":-1065359330,"lat":417485637}}},{"delta":{"node-LatLon":{"lon":-1065283762,"lat":417497543}}},{"delta":{"node-LatLon":{"lon":-1065215939,"lat":417523097}}},{"delta":{"node-LatLon":{"lon":-1065145106,"lat":417539870}}},{"delta":{"node-LatLon":{"lon":-1065078198,"lat":417513374}}},{"delta":{"node-LatLon":{"lon":-1065015853,"lat":417480011}}},{"delta":{"node-LatLon":{"lon":-1064958078,"lat":417441842}}},{"delta":{"node-LatLon":{"lon":-1064922715,"lat":417389692}}},{"delta":{"node-LatLon":{"lon":-1064872664,"lat":417345234}}},{"delta":{"node-LatLon":{"lon":-1064805541,"lat":417317528}}},{"delta":{"node-LatLon":{"lon":-1064737065,"lat":417291583}}},{"delta":{"node-LatLon":{"lon":-1064668140,"lat":417265497}}},{"delta":{"node-LatLon":{"lon":-1064598834,"lat":417239175}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417412478,"long":-1068329876}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023629,"speed":23.16,"longitude":-105.0479939},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":32,"serialNumber":15461,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000EF64E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415981013,"long":-1062070609},"name":"westbound_I80_267.19_272.06_SAT-1F82D7A2_RC_ARLI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062090421,"lat":415980971}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062129021,"lat":415980789}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415981013,"long":-1062070609}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":54}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023711,"speed":23.16,"longitude":-105.0479398},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":36,"serialNumber":15465,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.753Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"000000000000097BE1","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416329581,"long":-1062818144},"name":"westbound_I80_255.6_267.19_SAT-EF31CF04_RC_EMI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062861444,"lat":416357241}}},{"delta":{"node-LatLon":{"lon":-1062891617,"lat":416376465}}},{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062961089,"lat":416403834}}},{"delta":{"node-LatLon":{"lon":-1062999651,"lat":416410539}}},{"delta":{"node-LatLon":{"lon":-1063038256,"lat":416417110}}},{"delta":{"node-LatLon":{"lon":-1063075838,"lat":416423525}}},{"delta":{"node-LatLon":{"lon":-1063113422,"lat":416429935}}},{"delta":{"node-LatLon":{"lon":-1063151010,"lat":416436333}}},{"delta":{"node-LatLon":{"lon":-1063187758,"lat":416444929}}},{"delta":{"node-LatLon":{"lon":-1063221748,"lat":416458478}}},{"delta":{"node-LatLon":{"lon":-1063254248,"lat":416474223}}},{"delta":{"node-LatLon":{"lon":-1063286767,"lat":416489947}}},{"delta":{"node-LatLon":{"lon":-1063319286,"lat":416505671}}},{"delta":{"node-LatLon":{"lon":-1063351803,"lat":416521398}}},{"delta":{"node-LatLon":{"lon":-1063384308,"lat":416537141}}},{"delta":{"node-LatLon":{"lon":-1063416537,"lat":416552741}}},{"delta":{"node-LatLon":{"lon":-1063448756,"lat":416568353}}},{"delta":{"node-LatLon":{"lon":-1063480997,"lat":416583940}}},{"delta":{"node-LatLon":{"lon":-1063513230,"lat":416599539}}},{"delta":{"node-LatLon":{"lon":-1063545479,"lat":416615118}}},{"delta":{"node-LatLon":{"lon":-1063577703,"lat":416630746}}},{"delta":{"node-LatLon":{"lon":-1063609979,"lat":416646315}}},{"delta":{"node-LatLon":{"lon":-1063642246,"lat":416661894}}},{"delta":{"node-LatLon":{"lon":-1063674320,"lat":416677693}}},{"delta":{"node-LatLon":{"lon":-1063702475,"lat":416697159}}},{"delta":{"node-LatLon":{"lon":-1063724503,"lat":416721905}}},{"delta":{"node-LatLon":{"lon":-1063738013,"lat":416749885}}},{"delta":{"node-LatLon":{"lon":-1063745688,"lat":416779149}}},{"delta":{"node-LatLon":{"lon":-1063757512,"lat":416807580}}},{"delta":{"node-LatLon":{"lon":-1063775542,"lat":416834147}}},{"delta":{"node-LatLon":{"lon":-1063793398,"lat":416858977}}},{"delta":{"node-LatLon":{"lon":-1063809837,"lat":416884350}}},{"delta":{"node-LatLon":{"lon":-1063824918,"lat":416910195}}},{"delta":{"node-LatLon":{"lon":-1063839847,"lat":416936091}}},{"delta":{"node-LatLon":{"lon":-1063856289,"lat":416961436}}},{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063910309,"lat":417002755}}},{"delta":{"node-LatLon":{"lon":-1063944810,"lat":417016237}}},{"delta":{"node-LatLon":{"lon":-1063979929,"lat":417028841}}},{"delta":{"node-LatLon":{"lon":-1064015050,"lat":417041442}}},{"delta":{"node-LatLon":{"lon":-1064050617,"lat":417052787}}},{"delta":{"node-LatLon":{"lon":-1064088491,"lat":417058422}}},{"delta":{"node-LatLon":{"lon":-1064127128,"lat":417059995}}},{"delta":{"node-LatLon":{"lon":-1064165769,"lat":417061539}}},{"delta":{"node-LatLon":{"lon":-1064204408,"lat":417063119}}},{"delta":{"node-LatLon":{"lon":-1064242489,"lat":417067748}}},{"delta":{"node-LatLon":{"lon":-1064278067,"lat":417078928}}},{"delta":{"node-LatLon":{"lon":-1064309216,"lat":417095993}}},{"delta":{"node-LatLon":{"lon":-1064338068,"lat":417115288}}},{"delta":{"node-LatLon":{"lon":-1064366996,"lat":417134521}}},{"delta":{"node-LatLon":{"lon":-1064396523,"lat":417152988}}},{"delta":{"node-LatLon":{"lon":-1064427177,"lat":417170394}}},{"delta":{"node-LatLon":{"lon":-1064458838,"lat":417186756}}},{"delta":{"node-LatLon":{"lon":-1064491487,"lat":417201990}}},{"delta":{"node-LatLon":{"lon":-1064525046,"lat":417216068}}},{"delta":{"node-LatLon":{"lon":-1064559666,"lat":417229448}}},{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416329581,"long":-1062818144}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023629,"speed":23.16,"longitude":-105.0479939},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":33,"serialNumber":15462,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.653Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"00000000000010847D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415976300,"long":-1062132565},"name":"eastbound_I80_272.06_279.86_SAT-A456B6BD_RC_ARLI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060830479,"lat":415423609}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415976300,"long":-1062132565}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":36}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.102367,"speed":23.16,"longitude":-105.0479669},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":35,"serialNumber":15464,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.753Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31576,"packetID":"000000000000043991","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417245737,"long":-1064616173},"name":"eastbound_I80_255.6_267.19_SAT-9BEE74D0_RC_EMI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1064598834,"lat":417239175}}},{"delta":{"node-LatLon":{"lon":-1064564140,"lat":417226077}}},{"delta":{"node-LatLon":{"lon":-1064529505,"lat":417212891}}},{"delta":{"node-LatLon":{"lon":-1064496024,"lat":417198853}}},{"delta":{"node-LatLon":{"lon":-1064463440,"lat":417183676}}},{"delta":{"node-LatLon":{"lon":-1064431804,"lat":417167410}}},{"delta":{"node-LatLon":{"lon":-1064401163,"lat":417150110}}},{"delta":{"node-LatLon":{"lon":-1064371651,"lat":417131742}}},{"delta":{"node-LatLon":{"lon":-1064342280,"lat":417112106}}},{"delta":{"node-LatLon":{"lon":-1064312928,"lat":417092456}}},{"delta":{"node-LatLon":{"lon":-1064281084,"lat":417075243}}},{"delta":{"node-LatLon":{"lon":-1064244933,"lat":417063737}}},{"delta":{"node-LatLon":{"lon":-1064206236,"lat":417058710}}},{"delta":{"node-LatLon":{"lon":-1064168081,"lat":417057202}}},{"delta":{"node-LatLon":{"lon":-1064129929,"lat":417055664}}},{"delta":{"node-LatLon":{"lon":-1064091774,"lat":417054155}}},{"delta":{"node-LatLon":{"lon":-1064054270,"lat":417049080}}},{"delta":{"node-LatLon":{"lon":-1064019101,"lat":417037984}}},{"delta":{"node-LatLon":{"lon":-1063985061,"lat":417025732}}},{"delta":{"node-LatLon":{"lon":-1063951019,"lat":417013482}}},{"delta":{"node-LatLon":{"lon":-1063917284,"lat":417000788}}},{"delta":{"node-LatLon":{"lon":-1063887416,"lat":416983573}}},{"delta":{"node-LatLon":{"lon":-1063863549,"lat":416961722}}},{"delta":{"node-LatLon":{"lon":-1063846461,"lat":416936273}}},{"delta":{"node-LatLon":{"lon":-1063831379,"lat":416910073}}},{"delta":{"node-LatLon":{"lon":-1063816138,"lat":416883925}}},{"delta":{"node-LatLon":{"lon":-1063799617,"lat":416858220}}},{"delta":{"node-LatLon":{"lon":-1063781616,"lat":416833080}}},{"delta":{"node-LatLon":{"lon":-1063763325,"lat":416806477}}},{"delta":{"node-LatLon":{"lon":-1063751513,"lat":416777919}}},{"delta":{"node-LatLon":{"lon":-1063743848,"lat":416748530}}},{"delta":{"node-LatLon":{"lon":-1063730315,"lat":416720424}}},{"delta":{"node-LatLon":{"lon":-1063708354,"lat":416695491}}},{"delta":{"node-LatLon":{"lon":-1063680444,"lat":416675556}}},{"delta":{"node-LatLon":{"lon":-1063648291,"lat":416659518}}},{"delta":{"node-LatLon":{"lon":-1063615844,"lat":416643807}}},{"delta":{"node-LatLon":{"lon":-1063583366,"lat":416628132}}},{"delta":{"node-LatLon":{"lon":-1063550917,"lat":416612423}}},{"delta":{"node-LatLon":{"lon":-1063518397,"lat":416596725}}},{"delta":{"node-LatLon":{"lon":-1063485899,"lat":416581001}}},{"delta":{"node-LatLon":{"lon":-1063453403,"lat":416565276}}},{"delta":{"node-LatLon":{"lon":-1063420938,"lat":416549517}}},{"delta":{"node-LatLon":{"lon":-1063388402,"lat":416533840}}},{"delta":{"node-LatLon":{"lon":-1063355954,"lat":416518111}}},{"delta":{"node-LatLon":{"lon":-1063323497,"lat":416502393}}},{"delta":{"node-LatLon":{"lon":-1063291009,"lat":416486712}}},{"delta":{"node-LatLon":{"lon":-1063258568,"lat":416470977}}},{"delta":{"node-LatLon":{"lon":-1063226121,"lat":416455250}}},{"delta":{"node-LatLon":{"lon":-1063191824,"lat":416441408}}},{"delta":{"node-LatLon":{"lon":-1063154787,"lat":416432390}}},{"delta":{"node-LatLon":{"lon":-1063116772,"lat":416425883}}},{"delta":{"node-LatLon":{"lon":-1063078751,"lat":416419398}}},{"delta":{"node-LatLon":{"lon":-1063040728,"lat":416412924}}},{"delta":{"node-LatLon":{"lon":-1063002941,"lat":416406471}}},{"delta":{"node-LatLon":{"lon":-1062965166,"lat":416399984}}},{"delta":{"node-LatLon":{"lon":-1062928900,"lat":416389943}}},{"delta":{"node-LatLon":{"lon":-1062896756,"lat":416373819}}},{"delta":{"node-LatLon":{"lon":-1062867209,"lat":416355008}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417245737,"long":-1064616173}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31576}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.102367,"speed":23.16,"longitude":-105.0479669},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":34,"serialNumber":15463,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.653Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000C4306","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415413487,"long":-1060812632},"name":"westbound_I80_272.06_279.86_SAT-84FB2473_RC_ARLI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060824406,"lat":415424958}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415413487,"long":-1060812632}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":48}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":28,"serialNumber":15457,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31584,"packetID":"0000000000000C776A","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412012058,"long":-1054342550},"name":"westbound_I80_325.78_322.6_SAT-1A7FD750_VSL_V002148","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054353231,"lat":412023546}}},{"delta":{"node-LatLon":{"lon":-1054363915,"lat":412035033}}},{"delta":{"node-LatLon":{"lon":-1054374628,"lat":412046505}}},{"delta":{"node-LatLon":{"lon":-1054384730,"lat":412058284}}},{"delta":{"node-LatLon":{"lon":-1054393246,"lat":412070758}}},{"delta":{"node-LatLon":{"lon":-1054401396,"lat":412083376}}},{"delta":{"node-LatLon":{"lon":-1054408178,"lat":412096432}}},{"delta":{"node-LatLon":{"lon":-1054411451,"lat":412110222}}},{"delta":{"node-LatLon":{"lon":-1054410494,"lat":412124215}}},{"delta":{"node-LatLon":{"lon":-1054406258,"lat":412138313}}},{"delta":{"node-LatLon":{"lon":-1054401538,"lat":412152329}}},{"delta":{"node-LatLon":{"lon":-1054396763,"lat":412166333}}},{"delta":{"node-LatLon":{"lon":-1054391999,"lat":412180340}}},{"delta":{"node-LatLon":{"lon":-1054387248,"lat":412194350}}},{"delta":{"node-LatLon":{"lon":-1054382654,"lat":412208387}}},{"delta":{"node-LatLon":{"lon":-1054380050,"lat":412222697}}},{"delta":{"node-LatLon":{"lon":-1054380942,"lat":412237122}}},{"delta":{"node-LatLon":{"lon":-1054384055,"lat":412251390}}},{"delta":{"node-LatLon":{"lon":-1054387241,"lat":412265649}}},{"delta":{"node-LatLon":{"lon":-1054387713,"lat":412280108}}},{"delta":{"node-LatLon":{"lon":-1054383702,"lat":412294247}}},{"delta":{"node-LatLon":{"lon":-1054376516,"lat":412307678}}},{"delta":{"node-LatLon":{"lon":-1054369571,"lat":412321177}}},{"delta":{"node-LatLon":{"lon":-1054366196,"lat":412335412}}},{"delta":{"node-LatLon":{"lon":-1054366933,"lat":412349870}}},{"delta":{"node-LatLon":{"lon":-1054369671,"lat":412364212}}},{"delta":{"node-LatLon":{"lon":-1054372542,"lat":412378541}}},{"delta":{"node-LatLon":{"lon":-1054376265,"lat":412392751}}},{"delta":{"node-LatLon":{"lon":-1054381673,"lat":412406651}}},{"delta":{"node-LatLon":{"lon":-1054388532,"lat":412420113}}},{"delta":{"node-LatLon":{"lon":-1054396624,"lat":412433185}}},{"delta":{"node-LatLon":{"lon":-1054404781,"lat":412446234}}},{"delta":{"node-LatLon":{"lon":-1054412998,"lat":412459262}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1000000000000011}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412012058,"long":-1054342550}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31584}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":31,"serialNumber":15460,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.553Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31547,"packetID":"0000000000000EA327","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416355008,"long":-1062867209},"name":"eastbound_I80_267.19_272.06_SAT-7ECE7CF3_RC_ARLI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062727519,"lat":416279817}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062690294,"lat":416271928}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062652620,"lat":416264564}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062614940,"lat":416257216}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062577255,"lat":416249886}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062539573,"lat":416242549}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062501815,"lat":416235141}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062464244,"lat":416227007}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062429289,"lat":416213939}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062398699,"lat":416195722}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062373783,"lat":416173151}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062353839,"lat":416148895}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062334576,"lat":416125335}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062315283,"lat":416101788}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062296038,"lat":416078220}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062276808,"lat":416054645}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062257093,"lat":416030536}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062236012,"lat":416006340}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062206968,"lat":415987559}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062171008,"lat":415977603}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062132565,"lat":415976300}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062093782,"lat":415976349}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416355008,"long":-1062867209}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31547}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":30,"serialNumber":15459,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31410,"packetID":"000000000000052CAD","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416762809,"long":-1079776048},"name":"westbound_I80_158.55_173.41_SAT-53B47E1D_RC_WAMI80WD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1079792654,"lat":416755214}}},{"delta":{"node-LatLon":{"lon":-1079842491,"lat":416732454}}},{"delta":{"node-LatLon":{"lon":-1079913673,"lat":416710891}}},{"delta":{"node-LatLon":{"lon":-1079988998,"lat":416700558}}},{"delta":{"node-LatLon":{"lon":-1080064380,"lat":416690465}}},{"delta":{"node-LatLon":{"lon":-1080140410,"lat":416680262}}},{"delta":{"node-LatLon":{"lon":-1080216433,"lat":416670036}}},{"delta":{"node-LatLon":{"lon":-1080292501,"lat":416659806}}},{"delta":{"node-LatLon":{"lon":-1080368608,"lat":416649545}}},{"delta":{"node-LatLon":{"lon":-1080444725,"lat":416639329}}},{"delta":{"node-LatLon":{"lon":-1080520774,"lat":416629083}}},{"delta":{"node-LatLon":{"lon":-1080596810,"lat":416618789}}},{"delta":{"node-LatLon":{"lon":-1080672394,"lat":416608577}}},{"delta":{"node-LatLon":{"lon":-1080747529,"lat":416598458}}},{"delta":{"node-LatLon":{"lon":-1080822654,"lat":416588304}}},{"delta":{"node-LatLon":{"lon":-1080898633,"lat":416578054}}},{"delta":{"node-LatLon":{"lon":-1080974597,"lat":416567750}}},{"delta":{"node-LatLon":{"lon":-1081050829,"lat":416557420}}},{"delta":{"node-LatLon":{"lon":-1081127325,"lat":416547044}}},{"delta":{"node-LatLon":{"lon":-1081203413,"lat":416535198}}},{"delta":{"node-LatLon":{"lon":-1081277846,"lat":416519549}}},{"delta":{"node-LatLon":{"lon":-1081352245,"lat":416503811}}},{"delta":{"node-LatLon":{"lon":-1081426652,"lat":416488040}}},{"delta":{"node-LatLon":{"lon":-1081501076,"lat":416472261}}},{"delta":{"node-LatLon":{"lon":-1081575983,"lat":416457952}}},{"delta":{"node-LatLon":{"lon":-1081652109,"lat":416449993}}},{"delta":{"node-LatLon":{"lon":-1081728290,"lat":416442318}}},{"delta":{"node-LatLon":{"lon":-1081805260,"lat":416434541}}},{"delta":{"node-LatLon":{"lon":-1081883037,"lat":416426768}}},{"delta":{"node-LatLon":{"lon":-1081960802,"lat":416418934}}},{"delta":{"node-LatLon":{"lon":-1082036873,"lat":416411275}}},{"delta":{"node-LatLon":{"lon":-1082112938,"lat":416403591}}},{"delta":{"node-LatLon":{"lon":-1082188943,"lat":416395924}}},{"delta":{"node-LatLon":{"lon":-1082264890,"lat":416388279}}},{"delta":{"node-LatLon":{"lon":-1082340832,"lat":416380614}}},{"delta":{"node-LatLon":{"lon":-1082416741,"lat":416370373}}},{"delta":{"node-LatLon":{"lon":-1082492308,"lat":416358699}}},{"delta":{"node-LatLon":{"lon":-1082567978,"lat":416347001}}},{"delta":{"node-LatLon":{"lon":-1082624827,"lat":416338280}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000110000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416762809,"long":-1079776048}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31410}},"msgCnt":44}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2079,"heading":78.75,"latitude":41.1023589,"speed":23.16,"longitude":-105.048021},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":29,"serialNumber":15458,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31410,"packetID":"00000000000006E136","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416331711,"long":-1082645377},"name":"eastbound_I80_158.55_173.41_SAT-C560983B_RC_WAMI80WI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082626530,"lat":416334663}}},{"delta":{"node-LatLon":{"lon":-1082569940,"lat":416343338}}},{"delta":{"node-LatLon":{"lon":-1082494293,"lat":416355057}}},{"delta":{"node-LatLon":{"lon":-1082418408,"lat":416366766}}},{"delta":{"node-LatLon":{"lon":-1082342222,"lat":416377204}}},{"delta":{"node-LatLon":{"lon":-1082266189,"lat":416384835}}},{"delta":{"node-LatLon":{"lon":-1082190159,"lat":416392484}}},{"delta":{"node-LatLon":{"lon":-1082114130,"lat":416400151}}},{"delta":{"node-LatLon":{"lon":-1082038109,"lat":416407878}}},{"delta":{"node-LatLon":{"lon":-1081962071,"lat":416415513}}},{"delta":{"node-LatLon":{"lon":-1081884585,"lat":416423333}}},{"delta":{"node-LatLon":{"lon":-1081807099,"lat":416431159}}},{"delta":{"node-LatLon":{"lon":-1081730361,"lat":416438843}}},{"delta":{"node-LatLon":{"lon":-1081654390,"lat":416446481}}},{"delta":{"node-LatLon":{"lon":-1081578471,"lat":416454403}}},{"delta":{"node-LatLon":{"lon":-1081503389,"lat":416468376}}},{"delta":{"node-LatLon":{"lon":-1081428908,"lat":416484193}}},{"delta":{"node-LatLon":{"lon":-1081354605,"lat":416499942}}},{"delta":{"node-LatLon":{"lon":-1081280498,"lat":416515672}}},{"delta":{"node-LatLon":{"lon":-1081206345,"lat":416531284}}},{"delta":{"node-LatLon":{"lon":-1081130243,"lat":416543380}}},{"delta":{"node-LatLon":{"lon":-1081053650,"lat":416553747}}},{"delta":{"node-LatLon":{"lon":-1080977254,"lat":416564119}}},{"delta":{"node-LatLon":{"lon":-1080901037,"lat":416574429}}},{"delta":{"node-LatLon":{"lon":-1080824822,"lat":416584754}}},{"delta":{"node-LatLon":{"lon":-1080749783,"lat":416594899}}},{"delta":{"node-LatLon":{"lon":-1080674747,"lat":416605063}}},{"delta":{"node-LatLon":{"lon":-1080599110,"lat":416615260}}},{"delta":{"node-LatLon":{"lon":-1080522881,"lat":416625527}}},{"delta":{"node-LatLon":{"lon":-1080446654,"lat":416635808}}},{"delta":{"node-LatLon":{"lon":-1080370892,"lat":416645963}}},{"delta":{"node-LatLon":{"lon":-1080295134,"lat":416656136}}},{"delta":{"node-LatLon":{"lon":-1080219094,"lat":416666380}}},{"delta":{"node-LatLon":{"lon":-1080142771,"lat":416676687}}},{"delta":{"node-LatLon":{"lon":-1080066436,"lat":416686950}}},{"delta":{"node-LatLon":{"lon":-1079990643,"lat":416697179}}},{"delta":{"node-LatLon":{"lon":-1079914851,"lat":416707417}}},{"delta":{"node-LatLon":{"lon":-1079842371,"lat":416727176}}},{"delta":{"node-LatLon":{"lon":-1079792300,"lat":416749998}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0011000000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416331711,"long":-1082645377}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5895}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31410}},"msgCnt":42}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023509,"speed":22.96,"longitude":-105.048075},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":27,"serialNumber":15456,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"0000000000000974CF","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411380266,"long":-1053516546},"name":"westbound_I80_332.29_328.74_SAT-33F06F41_VSL_V002179","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053530152,"lat":411390760}}},{"delta":{"node-LatLon":{"lon":-1053544178,"lat":411400926}}},{"delta":{"node-LatLon":{"lon":-1053559400,"lat":411410052}}},{"delta":{"node-LatLon":{"lon":-1053575650,"lat":411418098}}},{"delta":{"node-LatLon":{"lon":-1053593540,"lat":411425178}}},{"delta":{"node-LatLon":{"lon":-1053612259,"lat":411430899}}},{"delta":{"node-LatLon":{"lon":-1053631611,"lat":411435251}}},{"delta":{"node-LatLon":{"lon":-1053651429,"lat":411438163}}},{"delta":{"node-LatLon":{"lon":-1053671518,"lat":411439715}}},{"delta":{"node-LatLon":{"lon":-1053691660,"lat":411440843}}},{"delta":{"node-LatLon":{"lon":-1053711798,"lat":411442014}}},{"delta":{"node-LatLon":{"lon":-1053731780,"lat":411444206}}},{"delta":{"node-LatLon":{"lon":-1053751386,"lat":411447856}}},{"delta":{"node-LatLon":{"lon":-1053770441,"lat":411452906}}},{"delta":{"node-LatLon":{"lon":-1053788278,"lat":411458052}}},{"delta":{"node-LatLon":{"lon":-1053806111,"lat":411463205}}},{"delta":{"node-LatLon":{"lon":-1053823914,"lat":411468418}}},{"delta":{"node-LatLon":{"lon":-1053841210,"lat":411474512}}},{"delta":{"node-LatLon":{"lon":-1053857700,"lat":411481776}}},{"delta":{"node-LatLon":{"lon":-1053873524,"lat":411489854}}},{"delta":{"node-LatLon":{"lon":-1053889263,"lat":411498027}}},{"delta":{"node-LatLon":{"lon":-1053905019,"lat":411506182}}},{"delta":{"node-LatLon":{"lon":-1053920800,"lat":411514309}}},{"delta":{"node-LatLon":{"lon":-1053936557,"lat":411522463}}},{"delta":{"node-LatLon":{"lon":-1053951905,"lat":411530400}}},{"delta":{"node-LatLon":{"lon":-1053967181,"lat":411538416}}},{"delta":{"node-LatLon":{"lon":-1053982070,"lat":411546836}}},{"delta":{"node-LatLon":{"lon":-1053996450,"lat":411555749}}},{"delta":{"node-LatLon":{"lon":-1054010245,"lat":411565176}}},{"delta":{"node-LatLon":{"lon":-1054023504,"lat":411575034}}},{"delta":{"node-LatLon":{"lon":-1054036337,"lat":411585207}}},{"delta":{"node-LatLon":{"lon":-1054048431,"lat":411595888}}},{"delta":{"node-LatLon":{"lon":-1054059788,"lat":411607021}}},{"delta":{"node-LatLon":{"lon":-1054070551,"lat":411618485}}},{"delta":{"node-LatLon":{"lon":-1054080907,"lat":411630774}}},{"delta":{"node-LatLon":{"lon":-1054090598,"lat":411643369}}},{"delta":{"node-LatLon":{"lon":-1054099821,"lat":411656166}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411380266,"long":-1053516546}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023509,"speed":22.96,"longitude":-105.048075},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":26,"serialNumber":15455,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31529,"packetID":"000000000000067287","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411261912,"long":-1053190756},"name":"westbound_I80_334.3_332.29_SAT-7CB2A0D8_VSL_V002205","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053209808,"lat":411263198}}},{"delta":{"node-LatLon":{"lon":-1053228859,"lat":411264489}}},{"delta":{"node-LatLon":{"lon":-1053247874,"lat":411266056}}},{"delta":{"node-LatLon":{"lon":-1053266797,"lat":411268154}}},{"delta":{"node-LatLon":{"lon":-1053284753,"lat":411270823}}},{"delta":{"node-LatLon":{"lon":-1053302624,"lat":411273801}}},{"delta":{"node-LatLon":{"lon":-1053320485,"lat":411276816}}},{"delta":{"node-LatLon":{"lon":-1053338337,"lat":411279861}}},{"delta":{"node-LatLon":{"lon":-1053356049,"lat":411283332}}},{"delta":{"node-LatLon":{"lon":-1053373293,"lat":411287955}}},{"delta":{"node-LatLon":{"lon":-1053389921,"lat":411293728}}},{"delta":{"node-LatLon":{"lon":-1053405816,"lat":411300582}}},{"delta":{"node-LatLon":{"lon":-1053420870,"lat":411308448}}},{"delta":{"node-LatLon":{"lon":-1053434927,"lat":411317306}}},{"delta":{"node-LatLon":{"lon":-1053448810,"lat":411327586}}},{"delta":{"node-LatLon":{"lon":-1053462344,"lat":411338132}}},{"delta":{"node-LatLon":{"lon":-1053475910,"lat":411348654}}},{"delta":{"node-LatLon":{"lon":-1053489459,"lat":411359188}}},{"delta":{"node-LatLon":{"lon":-1053503009,"lat":411369723}}},{"delta":{"node-LatLon":{"lon":-1053516546,"lat":411380266}}},{"delta":{"node-LatLon":{"lon":-1053530152,"lat":411390760}}},{"delta":{"node-LatLon":{"lon":-1053544178,"lat":411400926}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411261912,"long":-1053190756}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31529}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.7625,"latitude":41.1023469,"speed":22.96,"longitude":-105.0481018},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":25,"serialNumber":15454,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.152Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"000000000000021245","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412730636,"long":-1055022420},"name":"westbound_I80_318.5_316.0_SAT-A649856C_VSL_V003668","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1055038524,"lat":412737393}}},{"delta":{"node-LatLon":{"lon":-1055054603,"lat":412744185}}},{"delta":{"node-LatLon":{"lon":-1055070731,"lat":412750911}}},{"delta":{"node-LatLon":{"lon":-1055086830,"lat":412757675}}},{"delta":{"node-LatLon":{"lon":-1055102919,"lat":412764454}}},{"delta":{"node-LatLon":{"lon":-1055119050,"lat":412771172}}},{"delta":{"node-LatLon":{"lon":-1055134655,"lat":412779343}}},{"delta":{"node-LatLon":{"lon":-1055148584,"lat":412789095}}},{"delta":{"node-LatLon":{"lon":-1055160661,"lat":412800171}}},{"delta":{"node-LatLon":{"lon":-1055171718,"lat":412811853}}},{"delta":{"node-LatLon":{"lon":-1055182800,"lat":412823521}}},{"delta":{"node-LatLon":{"lon":-1055193934,"lat":412835162}}},{"delta":{"node-LatLon":{"lon":-1055205033,"lat":412846820}}},{"delta":{"node-LatLon":{"lon":-1055216089,"lat":412858504}}},{"delta":{"node-LatLon":{"lon":-1055227100,"lat":412870211}}},{"delta":{"node-LatLon":{"lon":-1055238096,"lat":412881927}}},{"delta":{"node-LatLon":{"lon":-1055249775,"lat":412893620}}},{"delta":{"node-LatLon":{"lon":-1055264147,"lat":412903395}}},{"delta":{"node-LatLon":{"lon":-1055281500,"lat":412909856}}},{"delta":{"node-LatLon":{"lon":-1055300530,"lat":412912497}}},{"delta":{"node-LatLon":{"lon":-1055319936,"lat":412912720}}},{"delta":{"node-LatLon":{"lon":-1055339348,"lat":412912757}}},{"delta":{"node-LatLon":{"lon":-1055358760,"lat":412912763}}},{"delta":{"node-LatLon":{"lon":-1055378172,"lat":412912749}}},{"delta":{"node-LatLon":{"lon":-1055397583,"lat":412912794}}},{"delta":{"node-LatLon":{"lon":-1055416995,"lat":412912799}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412730636,"long":-1055022420}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":16}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.8,"latitude":41.1023428,"speed":22.84,"longitude":-105.0481287},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":24,"serialNumber":15453,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.152Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31529,"packetID":"000000000000074F73","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411295468,"long":-1053412343},"name":"eastbound_I80_333.32_336.16_SAT-04EA5301_VSL_V002192","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053397283,"lat":411286440}}},{"delta":{"node-LatLon":{"lon":-1053381215,"lat":411278476}}},{"delta":{"node-LatLon":{"lon":-1053364267,"lat":411271631}}},{"delta":{"node-LatLon":{"lon":-1053346537,"lat":411266040}}},{"delta":{"node-LatLon":{"lon":-1053328222,"lat":411261661}}},{"delta":{"node-LatLon":{"lon":-1053309440,"lat":411258607}}},{"delta":{"node-LatLon":{"lon":-1053290366,"lat":411256889}}},{"delta":{"node-LatLon":{"lon":-1053271167,"lat":411256326}}},{"delta":{"node-LatLon":{"lon":-1053252031,"lat":411256011}}},{"delta":{"node-LatLon":{"lon":-1053232894,"lat":411255714}}},{"delta":{"node-LatLon":{"lon":-1053213757,"lat":411255411}}},{"delta":{"node-LatLon":{"lon":-1053194621,"lat":411255101}}},{"delta":{"node-LatLon":{"lon":-1053175485,"lat":411254779}}},{"delta":{"node-LatLon":{"lon":-1053156349,"lat":411254454}}},{"delta":{"node-LatLon":{"lon":-1053137212,"lat":411254156}}},{"delta":{"node-LatLon":{"lon":-1053118075,"lat":411253866}}},{"delta":{"node-LatLon":{"lon":-1053098943,"lat":411253445}}},{"delta":{"node-LatLon":{"lon":-1053079915,"lat":411251929}}},{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1053023237,"lat":411244960}}},{"delta":{"node-LatLon":{"lon":-1053004357,"lat":411242579}}},{"delta":{"node-LatLon":{"lon":-1052985469,"lat":411240234}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052948155,"lat":411233869}}},{"delta":{"node-LatLon":{"lon":-1052930037,"lat":411229208}}},{"delta":{"node-LatLon":{"lon":-1052912393,"lat":411223601}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052878140,"lat":411209333}}},{"delta":{"node-LatLon":{"lon":-1052861535,"lat":411200909}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411295468,"long":-1053412343}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12609}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31529}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.8,"latitude":41.1023428,"speed":22.84,"longitude":-105.0481287},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":23,"serialNumber":15452,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"0000000000000C3025","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411544031,"long":-1053986991},"name":"eastbound_I80_329.88_333.32_SAT-B0A8A48A_VSL_V002170","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053971893,"lat":411535445}}},{"delta":{"node-LatLon":{"lon":-1053956403,"lat":411527267}}},{"delta":{"node-LatLon":{"lon":-1053940802,"lat":411519210}}},{"delta":{"node-LatLon":{"lon":-1053925020,"lat":411511050}}},{"delta":{"node-LatLon":{"lon":-1053909255,"lat":411502872}}},{"delta":{"node-LatLon":{"lon":-1053893491,"lat":411494693}}},{"delta":{"node-LatLon":{"lon":-1053877704,"lat":411486540}}},{"delta":{"node-LatLon":{"lon":-1053861842,"lat":411478470}}},{"delta":{"node-LatLon":{"lon":-1053845388,"lat":411471122}}},{"delta":{"node-LatLon":{"lon":-1053828169,"lat":411464855}}},{"delta":{"node-LatLon":{"lon":-1053810387,"lat":411459552}}},{"delta":{"node-LatLon":{"lon":-1053792523,"lat":411454408}}},{"delta":{"node-LatLon":{"lon":-1053774674,"lat":411449233}}},{"delta":{"node-LatLon":{"lon":-1053756865,"lat":411444076}}},{"delta":{"node-LatLon":{"lon":-1053739051,"lat":411438927}}},{"delta":{"node-LatLon":{"lon":-1053721237,"lat":411433777}}},{"delta":{"node-LatLon":{"lon":-1053703432,"lat":411428613}}},{"delta":{"node-LatLon":{"lon":-1053685615,"lat":411423471}}},{"delta":{"node-LatLon":{"lon":-1053667804,"lat":411418317}}},{"delta":{"node-LatLon":{"lon":-1053649988,"lat":411413175}}},{"delta":{"node-LatLon":{"lon":-1053632183,"lat":411408010}}},{"delta":{"node-LatLon":{"lon":-1053614378,"lat":411402847}}},{"delta":{"node-LatLon":{"lon":-1053596576,"lat":411397677}}},{"delta":{"node-LatLon":{"lon":-1053578772,"lat":411392366}}},{"delta":{"node-LatLon":{"lon":-1053561555,"lat":411386056}}},{"delta":{"node-LatLon":{"lon":-1053545194,"lat":411378553}}},{"delta":{"node-LatLon":{"lon":-1053529834,"lat":411369925}}},{"delta":{"node-LatLon":{"lon":-1053515122,"lat":411360665}}},{"delta":{"node-LatLon":{"lon":-1053500460,"lat":411351359}}},{"delta":{"node-LatLon":{"lon":-1053485794,"lat":411342057}}},{"delta":{"node-LatLon":{"lon":-1053471129,"lat":411332755}}},{"delta":{"node-LatLon":{"lon":-1053456470,"lat":411323446}}},{"delta":{"node-LatLon":{"lon":-1053441803,"lat":411314147}}},{"delta":{"node-LatLon":{"lon":-1053427082,"lat":411304799}}},{"delta":{"node-LatLon":{"lon":-1053412343,"lat":411295468}}},{"delta":{"node-LatLon":{"lon":-1053397283,"lat":411286440}}},{"delta":{"node-LatLon":{"lon":-1053381215,"lat":411278476}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411544031,"long":-1053986991}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":21}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023389,"speed":22.8,"longitude":-105.0481553},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":22,"serialNumber":15451,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:08.052Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31584,"packetID":"0000000000000D2C74","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412034419,"long":-1054370810},"name":"eastbound_I80_325.82_329.88_SAT-99766A8D_VSL_V002155","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}},{"delta":{"node-LatLon":{"lon":-1054338178,"lat":411999356}}},{"delta":{"node-LatLon":{"lon":-1054327183,"lat":411987515}}},{"delta":{"node-LatLon":{"lon":-1054316162,"lat":411975689}}},{"delta":{"node-LatLon":{"lon":-1054305136,"lat":411963865}}},{"delta":{"node-LatLon":{"lon":-1054294112,"lat":411952041}}},{"delta":{"node-LatLon":{"lon":-1054283086,"lat":411940217}}},{"delta":{"node-LatLon":{"lon":-1054272088,"lat":411928378}}},{"delta":{"node-LatLon":{"lon":-1054261070,"lat":411916551}}},{"delta":{"node-LatLon":{"lon":-1054250145,"lat":411904675}}},{"delta":{"node-LatLon":{"lon":-1054240737,"lat":411892089}}},{"delta":{"node-LatLon":{"lon":-1054233306,"lat":411878767}}},{"delta":{"node-LatLon":{"lon":-1054228088,"lat":411864884}}},{"delta":{"node-LatLon":{"lon":-1054224664,"lat":411850678}}},{"delta":{"node-LatLon":{"lon":-1054221515,"lat":411836434}}},{"delta":{"node-LatLon":{"lon":-1054217864,"lat":411822261}}},{"delta":{"node-LatLon":{"lon":-1054212576,"lat":411808389}}},{"delta":{"node-LatLon":{"lon":-1054205670,"lat":411794929}}},{"delta":{"node-LatLon":{"lon":-1054197171,"lat":411782001}}},{"delta":{"node-LatLon":{"lon":-1054188029,"lat":411769320}}},{"delta":{"node-LatLon":{"lon":-1054178851,"lat":411756655}}},{"delta":{"node-LatLon":{"lon":-1054169702,"lat":411743977}}},{"delta":{"node-LatLon":{"lon":-1054160547,"lat":411731223}}},{"delta":{"node-LatLon":{"lon":-1054151325,"lat":411718495}}},{"delta":{"node-LatLon":{"lon":-1054142157,"lat":411705746}}},{"delta":{"node-LatLon":{"lon":-1054132917,"lat":411693026}}},{"delta":{"node-LatLon":{"lon":-1054123777,"lat":411680265}}},{"delta":{"node-LatLon":{"lon":-1054114539,"lat":411667545}}},{"delta":{"node-LatLon":{"lon":-1054105341,"lat":411654808}}},{"delta":{"node-LatLon":{"lon":-1054096134,"lat":411642075}}},{"delta":{"node-LatLon":{"lon":-1054086588,"lat":411629487}}},{"delta":{"node-LatLon":{"lon":-1054076298,"lat":411617239}}},{"delta":{"node-LatLon":{"lon":-1054065465,"lat":411605534}}},{"delta":{"node-LatLon":{"lon":-1054053933,"lat":411594218}}},{"delta":{"node-LatLon":{"lon":-1054041764,"lat":411583290}}},{"delta":{"node-LatLon":{"lon":-1054029028,"lat":411572740}}},{"delta":{"node-LatLon":{"lon":-1054015535,"lat":411562740}}},{"delta":{"node-LatLon":{"lon":-1054001524,"lat":411553158}}},{"delta":{"node-LatLon":{"lon":-1053986991,"lat":411544031}}},{"delta":{"node-LatLon":{"lon":-1053971893,"lat":411535445}}},{"delta":{"node-LatLon":{"lon":-1053956403,"lat":411527267}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000011100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412034419,"long":-1054370810}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31584}},"msgCnt":23}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023389,"speed":22.8,"longitude":-105.0481553},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":21,"serialNumber":15450,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.952Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31413,"packetID":"0000000000000F6CF3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412309017,"long":-1054379125},"name":"eastbound_I80_323.85_325.82_SAT-0405F53D_VSL_V002136","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1054386377,"lat":412295717}}},{"delta":{"node-LatLon":{"lon":-1054390587,"lat":412281719}}},{"delta":{"node-LatLon":{"lon":-1054390501,"lat":412267361}}},{"delta":{"node-LatLon":{"lon":-1054387340,"lat":412253070}}},{"delta":{"node-LatLon":{"lon":-1054384188,"lat":412238776}}},{"delta":{"node-LatLon":{"lon":-1054383083,"lat":412224323}}},{"delta":{"node-LatLon":{"lon":-1054385250,"lat":412209941}}},{"delta":{"node-LatLon":{"lon":-1054389797,"lat":412195863}}},{"delta":{"node-LatLon":{"lon":-1054394498,"lat":412181812}}},{"delta":{"node-LatLon":{"lon":-1054399238,"lat":412167769}}},{"delta":{"node-LatLon":{"lon":-1054403962,"lat":412153723}}},{"delta":{"node-LatLon":{"lon":-1054408711,"lat":412139682}}},{"delta":{"node-LatLon":{"lon":-1054413260,"lat":412125813}}},{"delta":{"node-LatLon":{"lon":-1054415782,"lat":412111677}}},{"delta":{"node-LatLon":{"lon":-1054414034,"lat":412097480}}},{"delta":{"node-LatLon":{"lon":-1054408252,"lat":412083905}}},{"delta":{"node-LatLon":{"lon":-1054400204,"lat":412070975}}},{"delta":{"node-LatLon":{"lon":-1054391746,"lat":412058198}}},{"delta":{"node-LatLon":{"lon":-1054381691,"lat":412046104}}},{"delta":{"node-LatLon":{"lon":-1054370810,"lat":412034419}}},{"delta":{"node-LatLon":{"lon":-1054359947,"lat":412022723}}},{"delta":{"node-LatLon":{"lon":-1054349054,"lat":412011044}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001110000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412309017,"long":-1054379125}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12599}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31413}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9,"latitude":41.1023349,"speed":22.72,"longitude":-105.0481818},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":20,"serialNumber":15449,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.997Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24569,"packetID":"000000000000031CC6","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-60A2FC8C_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":24569}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.05,"latitude":41.102331,"speed":22.66,"longitude":-105.0482085},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":19,"serialNumber":15448,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24569,"packetID":"000000000000066E2C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414407115,"long":-1059458100},"name":"eastbound_I80_290.44_313.19_SAT-8CF74104_RC_LARI80WQDHLI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059291346,"lat":414382504}}},{"delta":{"node-LatLon":{"lon":-1059216139,"lat":414371403}}},{"delta":{"node-LatLon":{"lon":-1059140930,"lat":414360321}}},{"delta":{"node-LatLon":{"lon":-1059066277,"lat":414349272}}},{"delta":{"node-LatLon":{"lon":-1058991615,"lat":414338261}}},{"delta":{"node-LatLon":{"lon":-1058917936,"lat":414323988}}},{"delta":{"node-LatLon":{"lon":-1058850449,"lat":414297022}}},{"delta":{"node-LatLon":{"lon":-1058783417,"lat":414269380}}},{"delta":{"node-LatLon":{"lon":-1058716328,"lat":414241773}}},{"delta":{"node-LatLon":{"lon":-1058649253,"lat":414214149}}},{"delta":{"node-LatLon":{"lon":-1058581712,"lat":414186261}}},{"delta":{"node-LatLon":{"lon":-1058513627,"lat":414158213}}},{"delta":{"node-LatLon":{"lon":-1058445557,"lat":414130150}}},{"delta":{"node-LatLon":{"lon":-1058380711,"lat":414099504}}},{"delta":{"node-LatLon":{"lon":-1058332454,"lat":414054913}}},{"delta":{"node-LatLon":{"lon":-1058291219,"lat":414005996}}},{"delta":{"node-LatLon":{"lon":-1058249903,"lat":413956936}}},{"delta":{"node-LatLon":{"lon":-1058208508,"lat":413907914}}},{"delta":{"node-LatLon":{"lon":-1058167409,"lat":413859113}}},{"delta":{"node-LatLon":{"lon":-1058121254,"lat":413813192}}},{"delta":{"node-LatLon":{"lon":-1058059188,"lat":413779109}}},{"delta":{"node-LatLon":{"lon":-1057994981,"lat":413746928}}},{"delta":{"node-LatLon":{"lon":-1057930809,"lat":413714712}}},{"delta":{"node-LatLon":{"lon":-1057867697,"lat":413683015}}},{"delta":{"node-LatLon":{"lon":-1057804579,"lat":413651328}}},{"delta":{"node-LatLon":{"lon":-1057737049,"lat":413623514}}},{"delta":{"node-LatLon":{"lon":-1057662967,"lat":413603704}}},{"delta":{"node-LatLon":{"lon":-1057588887,"lat":413583895}}},{"delta":{"node-LatLon":{"lon":-1057516296,"lat":413564544}}},{"delta":{"node-LatLon":{"lon":-1057443317,"lat":413546135}}},{"delta":{"node-LatLon":{"lon":-1057367878,"lat":413535221}}},{"delta":{"node-LatLon":{"lon":-1057292600,"lat":413524353}}},{"delta":{"node-LatLon":{"lon":-1057217299,"lat":413513586}}},{"delta":{"node-LatLon":{"lon":-1057141027,"lat":413502656}}},{"delta":{"node-LatLon":{"lon":-1057064747,"lat":413491760}}},{"delta":{"node-LatLon":{"lon":-1056989068,"lat":413498824}}},{"delta":{"node-LatLon":{"lon":-1056912831,"lat":413504721}}},{"delta":{"node-LatLon":{"lon":-1056835658,"lat":413504909}}},{"delta":{"node-LatLon":{"lon":-1056757891,"lat":413505054}}},{"delta":{"node-LatLon":{"lon":-1056680124,"lat":413505252}}},{"delta":{"node-LatLon":{"lon":-1056603037,"lat":413505384}}},{"delta":{"node-LatLon":{"lon":-1056526628,"lat":413505543}}},{"delta":{"node-LatLon":{"lon":-1056450220,"lat":413505586}}},{"delta":{"node-LatLon":{"lon":-1056377627,"lat":413489027}}},{"delta":{"node-LatLon":{"lon":-1056311828,"lat":413459176}}},{"delta":{"node-LatLon":{"lon":-1056245669,"lat":413429174}}},{"delta":{"node-LatLon":{"lon":-1056183282,"lat":413395071}}},{"delta":{"node-LatLon":{"lon":-1056165228,"lat":413339197}}},{"delta":{"node-LatLon":{"lon":-1056160367,"lat":413283836}}},{"delta":{"node-LatLon":{"lon":-1056155562,"lat":413228473}}},{"delta":{"node-LatLon":{"lon":-1056150632,"lat":413171501}}},{"delta":{"node-LatLon":{"lon":-1056145513,"lat":413112925}}},{"delta":{"node-LatLon":{"lon":-1056139692,"lat":413054402}}},{"delta":{"node-LatLon":{"lon":-1056094488,"lat":413014131}}},{"delta":{"node-LatLon":{"lon":-1056025680,"lat":412995553}}},{"delta":{"node-LatLon":{"lon":-1055953535,"lat":412976113}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414407115,"long":-1059458100}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":24569}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.05,"latitude":41.102331,"speed":22.66,"longitude":-105.0482085},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":18,"serialNumber":15447,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":24213,"packetID":"00000000000003F64F","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411251929,"long":-1053079915},"name":"eastbound_I80_335.11_348.36_SAT-70957D0D_RC_CHEYI80WHARI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1053061014,"lat":411249645}}},{"delta":{"node-LatLon":{"lon":-1053042122,"lat":411247319}}},{"delta":{"node-LatLon":{"lon":-1052966667,"lat":411237536}}},{"delta":{"node-LatLon":{"lon":-1052895308,"lat":411217079}}},{"delta":{"node-LatLon":{"lon":-1052828416,"lat":411183958}}},{"delta":{"node-LatLon":{"lon":-1052762243,"lat":411149986}}},{"delta":{"node-LatLon":{"lon":-1052694431,"lat":411120945}}},{"delta":{"node-LatLon":{"lon":-1052623255,"lat":411100002}}},{"delta":{"node-LatLon":{"lon":-1052552081,"lat":411079062}}},{"delta":{"node-LatLon":{"lon":-1052479703,"lat":411059291}}},{"delta":{"node-LatLon":{"lon":-1052404522,"lat":411047559}}},{"delta":{"node-LatLon":{"lon":-1052327830,"lat":411046722}}},{"delta":{"node-LatLon":{"lon":-1052251668,"lat":411043133}}},{"delta":{"node-LatLon":{"lon":-1052181375,"lat":411021106}}},{"delta":{"node-LatLon":{"lon":-1052115683,"lat":410991356}}},{"delta":{"node-LatLon":{"lon":-1052050763,"lat":410960746}}},{"delta":{"node-LatLon":{"lon":-1051976364,"lat":410951581}}},{"delta":{"node-LatLon":{"lon":-1051901229,"lat":410960621}}},{"delta":{"node-LatLon":{"lon":-1051825257,"lat":410964045}}},{"delta":{"node-LatLon":{"lon":-1051748594,"lat":410968835}}},{"delta":{"node-LatLon":{"lon":-1051672128,"lat":410975297}}},{"delta":{"node-LatLon":{"lon":-1051597070,"lat":410985937}}},{"delta":{"node-LatLon":{"lon":-1051522865,"lat":410997958}}},{"delta":{"node-LatLon":{"lon":-1051447302,"lat":410993106}}},{"delta":{"node-LatLon":{"lon":-1051371114,"lat":410985628}}},{"delta":{"node-LatLon":{"lon":-1051294312,"lat":410986015}}},{"delta":{"node-LatLon":{"lon":-1051217495,"lat":410986235}}},{"delta":{"node-LatLon":{"lon":-1051141211,"lat":410979532}}},{"delta":{"node-LatLon":{"lon":-1051065300,"lat":410971078}}},{"delta":{"node-LatLon":{"lon":-1050990664,"lat":410982109}}},{"delta":{"node-LatLon":{"lon":-1050915862,"lat":410993050}}},{"delta":{"node-LatLon":{"lon":-1050839582,"lat":410997762}}},{"delta":{"node-LatLon":{"lon":-1050763005,"lat":410998142}}},{"delta":{"node-LatLon":{"lon":-1050686406,"lat":410997353}}},{"delta":{"node-LatLon":{"lon":-1050610683,"lat":411003862}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411251929,"long":-1053079915}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":6011}},{"item":{"itis":5127}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":24213}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.102327,"speed":22.54,"longitude":-105.0482348},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":17,"serialNumber":15446,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.756Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":23113,"packetID":"000000000000064D7E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":412669811,"long":-1109265496},"name":"eastbound_I80_6.94_8.45_SAT-C9A7ABD9_VSL_V004766","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1109245942,"lat":412667616}}},{"delta":{"node-LatLon":{"lon":-1109227078,"lat":412665173}}},{"delta":{"node-LatLon":{"lon":-1109208218,"lat":412662718}}},{"delta":{"node-LatLon":{"lon":-1109189533,"lat":412659588}}},{"delta":{"node-LatLon":{"lon":-1109170944,"lat":412656149}}},{"delta":{"node-LatLon":{"lon":-1109152362,"lat":412652687}}},{"delta":{"node-LatLon":{"lon":-1109133790,"lat":412649197}}},{"delta":{"node-LatLon":{"lon":-1109115215,"lat":412645713}}},{"delta":{"node-LatLon":{"lon":-1109096639,"lat":412642235}}},{"delta":{"node-LatLon":{"lon":-1109078070,"lat":412638736}}},{"delta":{"node-LatLon":{"lon":-1109059500,"lat":412635242}}},{"delta":{"node-LatLon":{"lon":-1109040676,"lat":412631705}}},{"delta":{"node-LatLon":{"lon":-1109021836,"lat":412628219}}},{"delta":{"node-LatLon":{"lon":-1109002866,"lat":412625167}}},{"delta":{"node-LatLon":{"lon":-1108983731,"lat":412622770}}},{"delta":{"node-LatLon":{"lon":-1108964506,"lat":412620829}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":412669811,"long":-1109265496}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":23113}},"msgCnt":7}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.102327,"speed":22.54,"longitude":-105.0482348},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":16,"serialNumber":15445,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002224,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411709740,"long":-1048394120},"name":"wydot_sirius_4_2_SAT-7EFD0225","laneWidth":20000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048393730,"lat":411712450}}},{"delta":{"node-LatLon":{"lon":-1048383840,"lat":411767010}}},{"delta":{"node-LatLon":{"lon":-1048380500,"lat":411794860}}},{"delta":{"node-LatLon":{"lon":-1048379990,"lat":411809560}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":2574}},{"item":{"itis":12712}},{"item":{"itis":8709}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.1375,"latitude":41.1023232,"speed":22.5,"longitude":-105.0482612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":15,"serialNumber":15444,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.651Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002223,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411606840,"long":-1048289900},"name":"wydot_sirius_3_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048291070,"lat":411607850}}},{"delta":{"node-LatLon":{"lon":-1048323850,"lat":411632860}}},{"delta":{"node-LatLon":{"lon":-1048323850,"lat":411632860}}},{"delta":{"node-LatLon":{"lon":-1048338000,"lat":411643250}}},{"delta":{"node-LatLon":{"lon":-1048357350,"lat":411654510}}},{"delta":{"node-LatLon":{"lon":-1048383680,"lat":411667660}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":4868}},{"item":{"itis":5907}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79.1375,"latitude":41.1023232,"speed":22.5,"longitude":-105.0482612},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":14,"serialNumber":15443,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.551Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002222,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411713780,"long":-1048286250},"name":"wydot_sirius_2_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048286250,"lat":411712160}}},{"delta":{"node-LatLon":{"lon":-1048287580,"lat":411641030}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001111000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12579}},{"item":{"itis":8720}},{"item":{"itis":1025}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023195,"speed":22.4,"longitude":-105.0482875},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":13,"serialNumber":15442,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":21060,"packetID":212300001125002221,"urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":411751930,"long":-1048286330},"name":"wydot_sirius_1_2_SAT-7EFD0225","laneWidth":10000,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1048286640,"lat":411748120}}},{"delta":{"node-LatLon":{"lon":-1048286110,"lat":411713600}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000001111000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411751930,"long":-1048286330}}},"priority":6,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":7443}},{"item":{"itis":12579}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":21060}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023157,"speed":22.22,"longitude":-105.0483139},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":12,"serialNumber":15441,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.451Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31504,"packetID":"0000000000000C6FA0","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415389123,"long":-1060795306},"name":"eastbound_I80_280.36_291.0_SAT-9970CD4E_VSL_V000417","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060783562,"lat":415377559}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}},{"delta":{"node-LatLon":{"lon":-1060748924,"lat":415342529}}},{"delta":{"node-LatLon":{"lon":-1060725901,"lat":415319138}}},{"delta":{"node-LatLon":{"lon":-1060702891,"lat":415295740}}},{"delta":{"node-LatLon":{"lon":-1060677392,"lat":415274709}}},{"delta":{"node-LatLon":{"lon":-1060645465,"lat":415259440}}},{"delta":{"node-LatLon":{"lon":-1060611694,"lat":415246452}}},{"delta":{"node-LatLon":{"lon":-1060583936,"lat":415227230}}},{"delta":{"node-LatLon":{"lon":-1060567112,"lat":415201829}}},{"delta":{"node-LatLon":{"lon":-1060559250,"lat":415173268}}},{"delta":{"node-LatLon":{"lon":-1060551848,"lat":415144627}}},{"delta":{"node-LatLon":{"lon":-1060544578,"lat":415115967}}},{"delta":{"node-LatLon":{"lon":-1060537212,"lat":415087321}}},{"delta":{"node-LatLon":{"lon":-1060528192,"lat":415058965}}},{"delta":{"node-LatLon":{"lon":-1060513843,"lat":415031898}}},{"delta":{"node-LatLon":{"lon":-1060498684,"lat":415005075}}},{"delta":{"node-LatLon":{"lon":-1060479584,"lat":414979768}}},{"delta":{"node-LatLon":{"lon":-1060454612,"lat":414957536}}},{"delta":{"node-LatLon":{"lon":-1060424994,"lat":414938765}}},{"delta":{"node-LatLon":{"lon":-1060394265,"lat":414920704}}},{"delta":{"node-LatLon":{"lon":-1060362947,"lat":414903230}}},{"delta":{"node-LatLon":{"lon":-1060331139,"lat":414886261}}},{"delta":{"node-LatLon":{"lon":-1060299282,"lat":414869343}}},{"delta":{"node-LatLon":{"lon":-1060267401,"lat":414852453}}},{"delta":{"node-LatLon":{"lon":-1060236377,"lat":414836034}}},{"delta":{"node-LatLon":{"lon":-1060205413,"lat":414819550}}},{"delta":{"node-LatLon":{"lon":-1060174405,"lat":414803116}}},{"delta":{"node-LatLon":{"lon":-1060143426,"lat":414786651}}},{"delta":{"node-LatLon":{"lon":-1060112442,"lat":414770191}}},{"delta":{"node-LatLon":{"lon":-1060080853,"lat":414753421}}},{"delta":{"node-LatLon":{"lon":-1060049273,"lat":414736640}}},{"delta":{"node-LatLon":{"lon":-1060017699,"lat":414719856}}},{"delta":{"node-LatLon":{"lon":-1059986118,"lat":414703079}}},{"delta":{"node-LatLon":{"lon":-1059954550,"lat":414686289}}},{"delta":{"node-LatLon":{"lon":-1059923262,"lat":414669701}}},{"delta":{"node-LatLon":{"lon":-1059892003,"lat":414653083}}},{"delta":{"node-LatLon":{"lon":-1059860748,"lat":414636462}}},{"delta":{"node-LatLon":{"lon":-1059830894,"lat":414618511}}},{"delta":{"node-LatLon":{"lon":-1059806580,"lat":414596316}}},{"delta":{"node-LatLon":{"lon":-1059783729,"lat":414573041}}},{"delta":{"node-LatLon":{"lon":-1059760839,"lat":414549787}}},{"delta":{"node-LatLon":{"lon":-1059737946,"lat":414526535}}},{"delta":{"node-LatLon":{"lon":-1059715065,"lat":414503278}}},{"delta":{"node-LatLon":{"lon":-1059692206,"lat":414480008}}},{"delta":{"node-LatLon":{"lon":-1059665100,"lat":414457204}}},{"delta":{"node-LatLon":{"lon":-1059630733,"lat":414440918}}},{"delta":{"node-LatLon":{"lon":-1059592047,"lat":414431361}}},{"delta":{"node-LatLon":{"lon":-1059552953,"lat":414422717}}},{"delta":{"node-LatLon":{"lon":-1059513468,"lat":414415217}}},{"delta":{"node-LatLon":{"lon":-1059476558,"lat":414409805}}},{"delta":{"node-LatLon":{"lon":-1059439656,"lat":414404366}}},{"delta":{"node-LatLon":{"lon":-1059402750,"lat":414398944}}},{"delta":{"node-LatLon":{"lon":-1059365846,"lat":414393512}}},{"delta":{"node-LatLon":{"lon":-1059328946,"lat":414388067}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111100000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415389123,"long":-1060795306}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31504}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023157,"speed":22.22,"longitude":-105.0483139},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":11,"serialNumber":15440,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"000000000000028D2E","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415887613,"long":-1061814678},"name":"eastbound_I80_273.85_280.36_SAT-307505E1_VSL_V000424","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061768515,"lat":415860933}}},{"delta":{"node-LatLon":{"lon":-1061737747,"lat":415843066}}},{"delta":{"node-LatLon":{"lon":-1061706991,"lat":415825187}}},{"delta":{"node-LatLon":{"lon":-1061676217,"lat":415807327}}},{"delta":{"node-LatLon":{"lon":-1061645463,"lat":415789449}}},{"delta":{"node-LatLon":{"lon":-1061614689,"lat":415771591}}},{"delta":{"node-LatLon":{"lon":-1061584537,"lat":415754086}}},{"delta":{"node-LatLon":{"lon":-1061554447,"lat":415736525}}},{"delta":{"node-LatLon":{"lon":-1061524198,"lat":415719117}}},{"delta":{"node-LatLon":{"lon":-1061494074,"lat":415701589}}},{"delta":{"node-LatLon":{"lon":-1061463879,"lat":415684131}}},{"delta":{"node-LatLon":{"lon":-1061432150,"lat":415667054}}},{"delta":{"node-LatLon":{"lon":-1061396974,"lat":415654391}}},{"delta":{"node-LatLon":{"lon":-1061359292,"lat":415646802}}},{"delta":{"node-LatLon":{"lon":-1061320863,"lat":415641538}}},{"delta":{"node-LatLon":{"lon":-1061282426,"lat":415636308}}},{"delta":{"node-LatLon":{"lon":-1061244922,"lat":415631177}}},{"delta":{"node-LatLon":{"lon":-1061207418,"lat":415626048}}},{"delta":{"node-LatLon":{"lon":-1061169903,"lat":415620964}}},{"delta":{"node-LatLon":{"lon":-1061132571,"lat":415615219}}},{"delta":{"node-LatLon":{"lon":-1061096967,"lat":415605109}}},{"delta":{"node-LatLon":{"lon":-1061064131,"lat":415590319}}},{"delta":{"node-LatLon":{"lon":-1061032943,"lat":415573570}}},{"delta":{"node-LatLon":{"lon":-1061001748,"lat":415556828}}},{"delta":{"node-LatLon":{"lon":-1060970565,"lat":415540075}}},{"delta":{"node-LatLon":{"lon":-1060939622,"lat":415523077}}},{"delta":{"node-LatLon":{"lon":-1060912271,"lat":415503093}}},{"delta":{"node-LatLon":{"lon":-1060888721,"lat":415480493}}},{"delta":{"node-LatLon":{"lon":-1060865425,"lat":415457738}}},{"delta":{"node-LatLon":{"lon":-1060842121,"lat":415434989}}},{"delta":{"node-LatLon":{"lon":-1060818850,"lat":415412221}}},{"delta":{"node-LatLon":{"lon":-1060795306,"lat":415389123}}},{"delta":{"node-LatLon":{"lon":-1060772024,"lat":415365878}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415887613,"long":-1061814678}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":30}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023118,"speed":22.22,"longitude":-105.0483399},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":10,"serialNumber":15439,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.351Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000C462C","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416299496,"long":-1062778698},"name":"eastbound_I80_267.71_273.85_SAT-54C5D564_VSL_V000428","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}},{"delta":{"node-LatLon":{"lon":-1062709133,"lat":416275605}}},{"delta":{"node-LatLon":{"lon":-1062671455,"lat":416268251}}},{"delta":{"node-LatLon":{"lon":-1062633771,"lat":416260915}}},{"delta":{"node-LatLon":{"lon":-1062596100,"lat":416253544}}},{"delta":{"node-LatLon":{"lon":-1062558417,"lat":416246209}}},{"delta":{"node-LatLon":{"lon":-1062520744,"lat":416238847}}},{"delta":{"node-LatLon":{"lon":-1062482895,"lat":416231412}}},{"delta":{"node-LatLon":{"lon":-1062446311,"lat":416221159}}},{"delta":{"node-LatLon":{"lon":-1062413350,"lat":416205439}}},{"delta":{"node-LatLon":{"lon":-1062385484,"lat":416184907}}},{"delta":{"node-LatLon":{"lon":-1062363439,"lat":416160690}}},{"delta":{"node-LatLon":{"lon":-1062344200,"lat":416137119}}},{"delta":{"node-LatLon":{"lon":-1062324886,"lat":416113582}}},{"delta":{"node-LatLon":{"lon":-1062305674,"lat":416089998}}},{"delta":{"node-LatLon":{"lon":-1062286421,"lat":416066433}}},{"delta":{"node-LatLon":{"lon":-1062267158,"lat":416042874}}},{"delta":{"node-LatLon":{"lon":-1062246994,"lat":416018215}}},{"delta":{"node-LatLon":{"lon":-1062222613,"lat":415995969}}},{"delta":{"node-LatLon":{"lon":-1062189595,"lat":415981343}}},{"delta":{"node-LatLon":{"lon":-1062151833,"lat":415976346}}},{"delta":{"node-LatLon":{"lon":-1062113298,"lat":415976355}}},{"delta":{"node-LatLon":{"lon":-1062074266,"lat":415976387}}},{"delta":{"node-LatLon":{"lon":-1062035235,"lat":415976340}}},{"delta":{"node-LatLon":{"lon":-1061996980,"lat":415971514}}},{"delta":{"node-LatLon":{"lon":-1061962779,"lat":415957510}}},{"delta":{"node-LatLon":{"lon":-1061929530,"lat":415942161}}},{"delta":{"node-LatLon":{"lon":-1061896505,"lat":415926815}}},{"delta":{"node-LatLon":{"lon":-1061863465,"lat":415911487}}},{"delta":{"node-LatLon":{"lon":-1061830559,"lat":415896001}}},{"delta":{"node-LatLon":{"lon":-1061799243,"lat":415878765}}},{"delta":{"node-LatLon":{"lon":-1061783879,"lat":415869849}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000111000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416299496,"long":-1062778698}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":34}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.1023118,"speed":22.22,"longitude":-105.0483399},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":9,"serialNumber":15438,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000EDB21","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416667387,"long":-1063664504},"name":"eastbound_I80_262.4_267.71_SAT-2AAB775E_VSL_V000433","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1063648291,"lat":416659518}}},{"delta":{"node-LatLon":{"lon":-1063632072,"lat":416651657}}},{"delta":{"node-LatLon":{"lon":-1063615844,"lat":416643807}}},{"delta":{"node-LatLon":{"lon":-1063599618,"lat":416635954}}},{"delta":{"node-LatLon":{"lon":-1063583366,"lat":416628132}}},{"delta":{"node-LatLon":{"lon":-1063567147,"lat":416620270}}},{"delta":{"node-LatLon":{"lon":-1063550917,"lat":416612423}}},{"delta":{"node-LatLon":{"lon":-1063534665,"lat":416604565}}},{"delta":{"node-LatLon":{"lon":-1063518397,"lat":416596725}}},{"delta":{"node-LatLon":{"lon":-1063502152,"lat":416588858}}},{"delta":{"node-LatLon":{"lon":-1063485899,"lat":416581001}}},{"delta":{"node-LatLon":{"lon":-1063469644,"lat":416573146}}},{"delta":{"node-LatLon":{"lon":-1063453403,"lat":416565276}}},{"delta":{"node-LatLon":{"lon":-1063437145,"lat":416557426}}},{"delta":{"node-LatLon":{"lon":-1063420938,"lat":416549517}}},{"delta":{"node-LatLon":{"lon":-1063404651,"lat":416541700}}},{"delta":{"node-LatLon":{"lon":-1063388402,"lat":416533840}}},{"delta":{"node-LatLon":{"lon":-1063372187,"lat":416525964}}},{"delta":{"node-LatLon":{"lon":-1063355954,"lat":416518111}}},{"delta":{"node-LatLon":{"lon":-1063339726,"lat":416510251}}},{"delta":{"node-LatLon":{"lon":-1063323497,"lat":416502393}}},{"delta":{"node-LatLon":{"lon":-1063307259,"lat":416494545}}},{"delta":{"node-LatLon":{"lon":-1063291009,"lat":416486712}}},{"delta":{"node-LatLon":{"lon":-1063274801,"lat":416478829}}},{"delta":{"node-LatLon":{"lon":-1063258568,"lat":416470977}}},{"delta":{"node-LatLon":{"lon":-1063242340,"lat":416463119}}},{"delta":{"node-LatLon":{"lon":-1063226121,"lat":416455250}}},{"delta":{"node-LatLon":{"lon":-1063209373,"lat":416447767}}},{"delta":{"node-LatLon":{"lon":-1063191824,"lat":416441408}}},{"delta":{"node-LatLon":{"lon":-1063173583,"lat":416436257}}},{"delta":{"node-LatLon":{"lon":-1063154787,"lat":416432390}}},{"delta":{"node-LatLon":{"lon":-1063135782,"lat":416429129}}},{"delta":{"node-LatLon":{"lon":-1063116772,"lat":416425883}}},{"delta":{"node-LatLon":{"lon":-1063097755,"lat":416422664}}},{"delta":{"node-LatLon":{"lon":-1063078751,"lat":416419398}}},{"delta":{"node-LatLon":{"lon":-1063059740,"lat":416416159}}},{"delta":{"node-LatLon":{"lon":-1063040728,"lat":416412924}}},{"delta":{"node-LatLon":{"lon":-1063021827,"lat":416409723}}},{"delta":{"node-LatLon":{"lon":-1063002941,"lat":416406471}}},{"delta":{"node-LatLon":{"lon":-1062984045,"lat":416403256}}},{"delta":{"node-LatLon":{"lon":-1062965166,"lat":416399984}}},{"delta":{"node-LatLon":{"lon":-1062946625,"lat":416395793}}},{"delta":{"node-LatLon":{"lon":-1062928900,"lat":416389943}}},{"delta":{"node-LatLon":{"lon":-1062912200,"lat":416382587}}},{"delta":{"node-LatLon":{"lon":-1062896756,"lat":416373819}}},{"delta":{"node-LatLon":{"lon":-1062881956,"lat":416364437}}},{"delta":{"node-LatLon":{"lon":-1062867209,"lat":416355008}}},{"delta":{"node-LatLon":{"lon":-1062852549,"lat":416345669}}},{"delta":{"node-LatLon":{"lon":-1062837900,"lat":416336319}}},{"delta":{"node-LatLon":{"lon":-1062823256,"lat":416326967}}},{"delta":{"node-LatLon":{"lon":-1062808616,"lat":416317611}}},{"delta":{"node-LatLon":{"lon":-1062793947,"lat":416308280}}},{"delta":{"node-LatLon":{"lon":-1062778698,"lat":416299496}}},{"delta":{"node-LatLon":{"lon":-1062762456,"lat":416291782}}},{"delta":{"node-LatLon":{"lon":-1062745352,"lat":416285198}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000110000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416667387,"long":-1063664504}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":31}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":7,"serialNumber":15436,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.151Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000C0339","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416385526,"long":-1062907286},"name":"westbound_I80_266.58_259.77_SAT-2470209F_VSL_V000430","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062961089,"lat":416403834}}},{"delta":{"node-LatLon":{"lon":-1062999651,"lat":416410539}}},{"delta":{"node-LatLon":{"lon":-1063038256,"lat":416417110}}},{"delta":{"node-LatLon":{"lon":-1063075838,"lat":416423525}}},{"delta":{"node-LatLon":{"lon":-1063113422,"lat":416429935}}},{"delta":{"node-LatLon":{"lon":-1063151010,"lat":416436333}}},{"delta":{"node-LatLon":{"lon":-1063187758,"lat":416444929}}},{"delta":{"node-LatLon":{"lon":-1063221748,"lat":416458478}}},{"delta":{"node-LatLon":{"lon":-1063254248,"lat":416474223}}},{"delta":{"node-LatLon":{"lon":-1063286767,"lat":416489947}}},{"delta":{"node-LatLon":{"lon":-1063319286,"lat":416505671}}},{"delta":{"node-LatLon":{"lon":-1063351803,"lat":416521398}}},{"delta":{"node-LatLon":{"lon":-1063384308,"lat":416537141}}},{"delta":{"node-LatLon":{"lon":-1063416537,"lat":416552741}}},{"delta":{"node-LatLon":{"lon":-1063448756,"lat":416568353}}},{"delta":{"node-LatLon":{"lon":-1063480997,"lat":416583940}}},{"delta":{"node-LatLon":{"lon":-1063513230,"lat":416599539}}},{"delta":{"node-LatLon":{"lon":-1063545479,"lat":416615118}}},{"delta":{"node-LatLon":{"lon":-1063577703,"lat":416630746}}},{"delta":{"node-LatLon":{"lon":-1063609979,"lat":416646315}}},{"delta":{"node-LatLon":{"lon":-1063642246,"lat":416661894}}},{"delta":{"node-LatLon":{"lon":-1063674320,"lat":416677693}}},{"delta":{"node-LatLon":{"lon":-1063702475,"lat":416697159}}},{"delta":{"node-LatLon":{"lon":-1063724503,"lat":416721905}}},{"delta":{"node-LatLon":{"lon":-1063738013,"lat":416749885}}},{"delta":{"node-LatLon":{"lon":-1063745688,"lat":416779149}}},{"delta":{"node-LatLon":{"lon":-1063757512,"lat":416807580}}},{"delta":{"node-LatLon":{"lon":-1063775542,"lat":416834147}}},{"delta":{"node-LatLon":{"lon":-1063793398,"lat":416858977}}},{"delta":{"node-LatLon":{"lon":-1063809837,"lat":416884350}}},{"delta":{"node-LatLon":{"lon":-1063824918,"lat":416910195}}},{"delta":{"node-LatLon":{"lon":-1063839847,"lat":416936091}}},{"delta":{"node-LatLon":{"lon":-1063856289,"lat":416961436}}},{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063894506,"lat":416994252}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416385526,"long":-1062907286}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":26}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":8,"serialNumber":15437,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.251Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31503,"packetID":"0000000000000FE5E4","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416973452,"long":-1063867317},"name":"westbound_I80_259.77_254.87_SAT-6C9DA4E2_VSL_V000435","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1063880112,"lat":416984440}}},{"delta":{"node-LatLon":{"lon":-1063894506,"lat":416994252}}},{"delta":{"node-LatLon":{"lon":-1063910309,"lat":417002755}}},{"delta":{"node-LatLon":{"lon":-1063927293,"lat":417009870}}},{"delta":{"node-LatLon":{"lon":-1063944810,"lat":417016237}}},{"delta":{"node-LatLon":{"lon":-1063962371,"lat":417022536}}},{"delta":{"node-LatLon":{"lon":-1063979929,"lat":417028841}}},{"delta":{"node-LatLon":{"lon":-1063997487,"lat":417035145}}},{"delta":{"node-LatLon":{"lon":-1064015050,"lat":417041442}}},{"delta":{"node-LatLon":{"lon":-1064032545,"lat":417047634}}},{"delta":{"node-LatLon":{"lon":-1064050617,"lat":417052787}}},{"delta":{"node-LatLon":{"lon":-1064069340,"lat":417056404}}},{"delta":{"node-LatLon":{"lon":-1064088491,"lat":417058422}}},{"delta":{"node-LatLon":{"lon":-1064107803,"lat":417059292}}},{"delta":{"node-LatLon":{"lon":-1064127128,"lat":417059995}}},{"delta":{"node-LatLon":{"lon":-1064146451,"lat":417060728}}},{"delta":{"node-LatLon":{"lon":-1064165769,"lat":417061539}}},{"delta":{"node-LatLon":{"lon":-1064185091,"lat":417062288}}},{"delta":{"node-LatLon":{"lon":-1064204408,"lat":417063119}}},{"delta":{"node-LatLon":{"lon":-1064223632,"lat":417064590}}},{"delta":{"node-LatLon":{"lon":-1064242489,"lat":417067748}}},{"delta":{"node-LatLon":{"lon":-1064260716,"lat":417072554}}},{"delta":{"node-LatLon":{"lon":-1064278067,"lat":417078928}}},{"delta":{"node-LatLon":{"lon":-1064294308,"lat":417086774}}},{"delta":{"node-LatLon":{"lon":-1064309216,"lat":417095993}}},{"delta":{"node-LatLon":{"lon":-1064323678,"lat":417105610}}},{"delta":{"node-LatLon":{"lon":-1064338068,"lat":417115288}}},{"delta":{"node-LatLon":{"lon":-1064352499,"lat":417124933}}},{"delta":{"node-LatLon":{"lon":-1064366996,"lat":417134521}}},{"delta":{"node-LatLon":{"lon":-1064381609,"lat":417143889}}},{"delta":{"node-LatLon":{"lon":-1064396523,"lat":417152988}}},{"delta":{"node-LatLon":{"lon":-1064411727,"lat":417161812}}},{"delta":{"node-LatLon":{"lon":-1064427177,"lat":417170394}}},{"delta":{"node-LatLon":{"lon":-1064442869,"lat":417178725}}},{"delta":{"node-LatLon":{"lon":-1064458838,"lat":417186756}}},{"delta":{"node-LatLon":{"lon":-1064475045,"lat":417194514}}},{"delta":{"node-LatLon":{"lon":-1064491487,"lat":417201990}}},{"delta":{"node-LatLon":{"lon":-1064508131,"lat":417209211}}},{"delta":{"node-LatLon":{"lon":-1064525046,"lat":417216068}}},{"delta":{"node-LatLon":{"lon":-1064542331,"lat":417222795}}},{"delta":{"node-LatLon":{"lon":-1064559666,"lat":417229448}}},{"delta":{"node-LatLon":{"lon":-1064577050,"lat":417236030}}},{"delta":{"node-LatLon":{"lon":-1064594442,"lat":417242599}}},{"delta":{"node-LatLon":{"lon":-1064611800,"lat":417249219}}},{"delta":{"node-LatLon":{"lon":-1064629183,"lat":417255803}}},{"delta":{"node-LatLon":{"lon":-1064646550,"lat":417262411}}},{"delta":{"node-LatLon":{"lon":-1064663938,"lat":417268988}}},{"delta":{"node-LatLon":{"lon":-1064681335,"lat":417275551}}},{"delta":{"node-LatLon":{"lon":-1064698689,"lat":417282178}}},{"delta":{"node-LatLon":{"lon":-1064715850,"lat":417288659}}},{"delta":{"node-LatLon":{"lon":-1064732992,"lat":417295169}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001100"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416973452,"long":-1063867317}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31503}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.95,"latitude":41.102308,"speed":22.22,"longitude":-105.0483658},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":6,"serialNumber":15435,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.053Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"00000000000004B2BA","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415980789,"long":-1062129021},"name":"westbound_I80_271.8_266.58_SAT-129A26E5_VSL_V000426","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}},{"delta":{"node-LatLon":{"lon":-1062166552,"lat":415981611}}},{"delta":{"node-LatLon":{"lon":-1062184813,"lat":415984845}}},{"delta":{"node-LatLon":{"lon":-1062201989,"lat":415990520}}},{"delta":{"node-LatLon":{"lon":-1062217437,"lat":415998517}}},{"delta":{"node-LatLon":{"lon":-1062230703,"lat":416008482}}},{"delta":{"node-LatLon":{"lon":-1062241451,"lat":416020041}}},{"delta":{"node-LatLon":{"lon":-1062251290,"lat":416032060}}},{"delta":{"node-LatLon":{"lon":-1062261128,"lat":416044081}}},{"delta":{"node-LatLon":{"lon":-1062270774,"lat":416055871}}},{"delta":{"node-LatLon":{"lon":-1062280417,"lat":416067663}}},{"delta":{"node-LatLon":{"lon":-1062290067,"lat":416079452}}},{"delta":{"node-LatLon":{"lon":-1062299712,"lat":416091244}}},{"delta":{"node-LatLon":{"lon":-1062309426,"lat":416103003}}},{"delta":{"node-LatLon":{"lon":-1062319170,"lat":416114748}}},{"delta":{"node-LatLon":{"lon":-1062328711,"lat":416126587}}},{"delta":{"node-LatLon":{"lon":-1062338232,"lat":416138435}}},{"delta":{"node-LatLon":{"lon":-1062347925,"lat":416150205}}},{"delta":{"node-LatLon":{"lon":-1062357563,"lat":416162000}}},{"delta":{"node-LatLon":{"lon":-1062368179,"lat":416174692}}},{"delta":{"node-LatLon":{"lon":-1062379892,"lat":416186820}}},{"delta":{"node-LatLon":{"lon":-1062393288,"lat":416197926}}},{"delta":{"node-LatLon":{"lon":-1062408108,"lat":416207958}}},{"delta":{"node-LatLon":{"lon":-1062424227,"lat":416216793}}},{"delta":{"node-LatLon":{"lon":-1062441506,"lat":416224292}}},{"delta":{"node-LatLon":{"lon":-1062459705,"lat":416230444}}},{"delta":{"node-LatLon":{"lon":-1062478641,"lat":416235175}}},{"delta":{"node-LatLon":{"lon":-1062497949,"lat":416238998}}},{"delta":{"node-LatLon":{"lon":-1062517273,"lat":416242774}}},{"delta":{"node-LatLon":{"lon":-1062536082,"lat":416246433}}},{"delta":{"node-LatLon":{"lon":-1062554889,"lat":416250101}}},{"delta":{"node-LatLon":{"lon":-1062573685,"lat":416253798}}},{"delta":{"node-LatLon":{"lon":-1062592489,"lat":416257471}}},{"delta":{"node-LatLon":{"lon":-1062611298,"lat":416261134}}},{"delta":{"node-LatLon":{"lon":-1062630102,"lat":416264808}}},{"delta":{"node-LatLon":{"lon":-1062648910,"lat":416268474}}},{"delta":{"node-LatLon":{"lon":-1062667716,"lat":416272143}}},{"delta":{"node-LatLon":{"lon":-1062686526,"lat":416275802}}},{"delta":{"node-LatLon":{"lon":-1062705320,"lat":416279506}}},{"delta":{"node-LatLon":{"lon":-1062723512,"lat":416283487}}},{"delta":{"node-LatLon":{"lon":-1062741156,"lat":416288664}}},{"delta":{"node-LatLon":{"lon":-1062758081,"lat":416295053}}},{"delta":{"node-LatLon":{"lon":-1062774179,"lat":416302552}}},{"delta":{"node-LatLon":{"lon":-1062789262,"lat":416311156}}},{"delta":{"node-LatLon":{"lon":-1062803697,"lat":416320374}}},{"delta":{"node-LatLon":{"lon":-1062818144,"lat":416329581}}},{"delta":{"node-LatLon":{"lon":-1062832563,"lat":416338813}}},{"delta":{"node-LatLon":{"lon":-1062847004,"lat":416348027}}},{"delta":{"node-LatLon":{"lon":-1062861444,"lat":416357241}}},{"delta":{"node-LatLon":{"lon":-1062876541,"lat":416366844}}},{"delta":{"node-LatLon":{"lon":-1062891617,"lat":416376465}}},{"delta":{"node-LatLon":{"lon":-1062907286,"lat":416385526}}},{"delta":{"node-LatLon":{"lon":-1062924240,"lat":416393168}}},{"delta":{"node-LatLon":{"lon":-1062942253,"lat":416399303}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415980789,"long":-1062129021}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":24}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9875,"latitude":41.1023005,"speed":22.12,"longitude":-105.0484177},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":5,"serialNumber":15434,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:07.053Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31475,"packetID":"0000000000000D81DE","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":415470937,"long":-1060871344},"name":"westbound_I80_279.36_271.8_SAT-06EB7A5B_VSL_V000422","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060906872,"lat":415505231}}},{"delta":{"node-LatLon":{"lon":-1060934236,"lat":415525587}}},{"delta":{"node-LatLon":{"lon":-1060965310,"lat":415542824}}},{"delta":{"node-LatLon":{"lon":-1060996772,"lat":415559666}}},{"delta":{"node-LatLon":{"lon":-1061028237,"lat":415576506}}},{"delta":{"node-LatLon":{"lon":-1061059706,"lat":415593342}}},{"delta":{"node-LatLon":{"lon":-1061092588,"lat":415608515}}},{"delta":{"node-LatLon":{"lon":-1061128419,"lat":415618971}}},{"delta":{"node-LatLon":{"lon":-1061166060,"lat":415624943}}},{"delta":{"node-LatLon":{"lon":-1061203924,"lat":415630154}}},{"delta":{"node-LatLon":{"lon":-1061241795,"lat":415635339}}},{"delta":{"node-LatLon":{"lon":-1061279673,"lat":415640497}}},{"delta":{"node-LatLon":{"lon":-1061317589,"lat":415645644}}},{"delta":{"node-LatLon":{"lon":-1061355497,"lat":415650826}}},{"delta":{"node-LatLon":{"lon":-1061392771,"lat":415657996}}},{"delta":{"node-LatLon":{"lon":-1061427646,"lat":415670204}}},{"delta":{"node-LatLon":{"lon":-1061459115,"lat":415686864}}},{"delta":{"node-LatLon":{"lon":-1061489394,"lat":415704469}}},{"delta":{"node-LatLon":{"lon":-1061519697,"lat":415722052}}},{"delta":{"node-LatLon":{"lon":-1061549992,"lat":415739645}}},{"delta":{"node-LatLon":{"lon":-1061580273,"lat":415757250}}},{"delta":{"node-LatLon":{"lon":-1061610581,"lat":415774831}}},{"delta":{"node-LatLon":{"lon":-1061641248,"lat":415792650}}},{"delta":{"node-LatLon":{"lon":-1061671923,"lat":415810463}}},{"delta":{"node-LatLon":{"lon":-1061702592,"lat":415828282}}},{"delta":{"node-LatLon":{"lon":-1061733271,"lat":415846093}}},{"delta":{"node-LatLon":{"lon":-1061763976,"lat":415863879}}},{"delta":{"node-LatLon":{"lon":-1061794560,"lat":415881656}}},{"delta":{"node-LatLon":{"lon":-1061825730,"lat":415898841}}},{"delta":{"node-LatLon":{"lon":-1061858422,"lat":415914356}}},{"delta":{"node-LatLon":{"lon":-1061891331,"lat":415929615}}},{"delta":{"node-LatLon":{"lon":-1061924211,"lat":415944910}}},{"delta":{"node-LatLon":{"lon":-1061957798,"lat":415960692}}},{"delta":{"node-LatLon":{"lon":-1061992345,"lat":415975173}}},{"delta":{"node-LatLon":{"lon":-1062030986,"lat":415980852}}},{"delta":{"node-LatLon":{"lon":-1062070609,"lat":415981013}}},{"delta":{"node-LatLon":{"lon":-1062110232,"lat":415980876}}},{"delta":{"node-LatLon":{"lon":-1062147810,"lat":415980793}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011110"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":415470937,"long":-1060871344}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31475}},"msgCnt":25}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":78.9875,"latitude":41.1023005,"speed":22.12,"longitude":-105.0484177},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":4,"serialNumber":15433,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.963Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31504,"packetID":"0000000000000B0C4D","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":414434951,"long":-1059587159},"name":"westbound_I80_289.5_279.36_SAT-FDFB3C3B_VSL_V000416","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1059606146,"lat":414439136}}},{"delta":{"node-LatLon":{"lon":-1059624866,"lat":414443931}}},{"delta":{"node-LatLon":{"lon":-1059658797,"lat":414459046}}},{"delta":{"node-LatLon":{"lon":-1059685629,"lat":414480816}}},{"delta":{"node-LatLon":{"lon":-1059708612,"lat":414504233}}},{"delta":{"node-LatLon":{"lon":-1059731631,"lat":414527631}}},{"delta":{"node-LatLon":{"lon":-1059754662,"lat":414551022}}},{"delta":{"node-LatLon":{"lon":-1059777663,"lat":414574431}}},{"delta":{"node-LatLon":{"lon":-1059800605,"lat":414597873}}},{"delta":{"node-LatLon":{"lon":-1059825019,"lat":414620504}}},{"delta":{"node-LatLon":{"lon":-1059854975,"lat":414638959}}},{"delta":{"node-LatLon":{"lon":-1059886652,"lat":414655790}}},{"delta":{"node-LatLon":{"lon":-1059918347,"lat":414672602}}},{"delta":{"node-LatLon":{"lon":-1059950027,"lat":414689430}}},{"delta":{"node-LatLon":{"lon":-1059981533,"lat":414706207}}},{"delta":{"node-LatLon":{"lon":-1060013094,"lat":414722925}}},{"delta":{"node-LatLon":{"lon":-1060044644,"lat":414739656}}},{"delta":{"node-LatLon":{"lon":-1060076151,"lat":414756434}}},{"delta":{"node-LatLon":{"lon":-1060107672,"lat":414773199}}},{"delta":{"node-LatLon":{"lon":-1060138668,"lat":414789614}}},{"delta":{"node-LatLon":{"lon":-1060169596,"lat":414806103}}},{"delta":{"node-LatLon":{"lon":-1060200600,"lat":414822512}}},{"delta":{"node-LatLon":{"lon":-1060231565,"lat":414838964}}},{"delta":{"node-LatLon":{"lon":-1060262552,"lat":414855394}}},{"delta":{"node-LatLon":{"lon":-1060294303,"lat":414872314}}},{"delta":{"node-LatLon":{"lon":-1060326101,"lat":414889184}}},{"delta":{"node-LatLon":{"lon":-1060357880,"lat":414906076}}},{"delta":{"node-LatLon":{"lon":-1060389415,"lat":414923223}}},{"delta":{"node-LatLon":{"lon":-1060420573,"lat":414940760}}},{"delta":{"node-LatLon":{"lon":-1060450509,"lat":414958838}}},{"delta":{"node-LatLon":{"lon":-1060475868,"lat":414980491}}},{"delta":{"node-LatLon":{"lon":-1060495507,"lat":415005280}}},{"delta":{"node-LatLon":{"lon":-1060510699,"lat":415031818}}},{"delta":{"node-LatLon":{"lon":-1060524843,"lat":415058673}}},{"delta":{"node-LatLon":{"lon":-1060533417,"lat":415086879}}},{"delta":{"node-LatLon":{"lon":-1060540264,"lat":415115378}}},{"delta":{"node-LatLon":{"lon":-1060547197,"lat":415143865}}},{"delta":{"node-LatLon":{"lon":-1060554077,"lat":415172359}}},{"delta":{"node-LatLon":{"lon":-1060561492,"lat":415200772}}},{"delta":{"node-LatLon":{"lon":-1060576552,"lat":415227429}}},{"delta":{"node-LatLon":{"lon":-1060600749,"lat":415249961}}},{"delta":{"node-LatLon":{"lon":-1060632200,"lat":415266697}}},{"delta":{"node-LatLon":{"lon":-1060666183,"lat":415280527}}},{"delta":{"node-LatLon":{"lon":-1060695463,"lat":415299353}}},{"delta":{"node-LatLon":{"lon":-1060719162,"lat":415322019}}},{"delta":{"node-LatLon":{"lon":-1060742498,"lat":415344904}}},{"delta":{"node-LatLon":{"lon":-1060765869,"lat":415367768}}},{"delta":{"node-LatLon":{"lon":-1060789259,"lat":415390622}}},{"delta":{"node-LatLon":{"lon":-1060812632,"lat":415413487}}},{"delta":{"node-LatLon":{"lon":-1060836139,"lat":415436453}}},{"delta":{"node-LatLon":{"lon":-1060859605,"lat":415459445}}},{"delta":{"node-LatLon":{"lon":-1060883068,"lat":415482438}}},{"delta":{"node-LatLon":{"lon":-1060894883,"lat":415493886}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000001111"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":414434951,"long":-1059587159}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":268}},{"item":{"itis":12619}},{"item":{"itis":8720}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31504}},"msgCnt":28}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":3,"serialNumber":15432,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.963Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31267,"packetID":"000000000000094275","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417772272,"long":-1073083802},"name":"westbound_I80_187.2_209.5_SAT-B0DDD576_RC_RAWI80WRSD","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1073103032,"lat":417770765}}},{"delta":{"node-LatLon":{"lon":-1073160734,"lat":417766344}}},{"delta":{"node-LatLon":{"lon":-1073237348,"lat":417761297}}},{"delta":{"node-LatLon":{"lon":-1073313648,"lat":417764434}}},{"delta":{"node-LatLon":{"lon":-1073388010,"lat":417777604}}},{"delta":{"node-LatLon":{"lon":-1073460227,"lat":417797785}}},{"delta":{"node-LatLon":{"lon":-1073532308,"lat":417818249}}},{"delta":{"node-LatLon":{"lon":-1073604685,"lat":417838835}}},{"delta":{"node-LatLon":{"lon":-1073677383,"lat":417859492}}},{"delta":{"node-LatLon":{"lon":-1073750200,"lat":417879909}}},{"delta":{"node-LatLon":{"lon":-1073825885,"lat":417892315}}},{"delta":{"node-LatLon":{"lon":-1073903361,"lat":417891911}}},{"delta":{"node-LatLon":{"lon":-1073980790,"lat":417878755}}},{"delta":{"node-LatLon":{"lon":-1074059270,"lat":417862672}}},{"delta":{"node-LatLon":{"lon":-1074138797,"lat":417849816}}},{"delta":{"node-LatLon":{"lon":-1074212379,"lat":417833423}}},{"delta":{"node-LatLon":{"lon":-1074285917,"lat":417816922}}},{"delta":{"node-LatLon":{"lon":-1074359753,"lat":417800402}}},{"delta":{"node-LatLon":{"lon":-1074433865,"lat":417783809}}},{"delta":{"node-LatLon":{"lon":-1074507971,"lat":417767209}}},{"delta":{"node-LatLon":{"lon":-1074582466,"lat":417750471}}},{"delta":{"node-LatLon":{"lon":-1074656974,"lat":417733772}}},{"delta":{"node-LatLon":{"lon":-1074730980,"lat":417717212}}},{"delta":{"node-LatLon":{"lon":-1074804466,"lat":417700741}}},{"delta":{"node-LatLon":{"lon":-1074877974,"lat":417684333}}},{"delta":{"node-LatLon":{"lon":-1074952181,"lat":417667699}}},{"delta":{"node-LatLon":{"lon":-1075026384,"lat":417651055}}},{"delta":{"node-LatLon":{"lon":-1075100631,"lat":417634583}}},{"delta":{"node-LatLon":{"lon":-1075174927,"lat":417618293}}},{"delta":{"node-LatLon":{"lon":-1075249229,"lat":417602021}}},{"delta":{"node-LatLon":{"lon":-1075324198,"lat":417585522}}},{"delta":{"node-LatLon":{"lon":-1075399202,"lat":417569122}}},{"delta":{"node-LatLon":{"lon":-1075474679,"lat":417552532}}},{"delta":{"node-LatLon":{"lon":-1075550650,"lat":417535815}}},{"delta":{"node-LatLon":{"lon":-1075626641,"lat":417519150}}},{"delta":{"node-LatLon":{"lon":-1075700169,"lat":417503005}}},{"delta":{"node-LatLon":{"lon":-1075773956,"lat":417487570}}},{"delta":{"node-LatLon":{"lon":-1075849915,"lat":417477896}}},{"delta":{"node-LatLon":{"lon":-1075927140,"lat":417472412}}},{"delta":{"node-LatLon":{"lon":-1076004368,"lat":417466944}}},{"delta":{"node-LatLon":{"lon":-1076078363,"lat":417461740}}},{"delta":{"node-LatLon":{"lon":-1076152354,"lat":417456501}}},{"delta":{"node-LatLon":{"lon":-1076228617,"lat":417451146}}},{"delta":{"node-LatLon":{"lon":-1076306386,"lat":417445637}}},{"delta":{"node-LatLon":{"lon":-1076384155,"lat":417440136}}},{"delta":{"node-LatLon":{"lon":-1076461786,"lat":417434636}}},{"delta":{"node-LatLon":{"lon":-1076539413,"lat":417429098}}},{"delta":{"node-LatLon":{"lon":-1076616980,"lat":417423684}}},{"delta":{"node-LatLon":{"lon":-1076694352,"lat":417417431}}},{"delta":{"node-LatLon":{"lon":-1076769822,"lat":417403428}}},{"delta":{"node-LatLon":{"lon":-1076844263,"lat":417386508}}},{"delta":{"node-LatLon":{"lon":-1076918694,"lat":417369570}}},{"delta":{"node-LatLon":{"lon":-1076992959,"lat":417352731}}},{"delta":{"node-LatLon":{"lon":-1077067009,"lat":417335868}}},{"delta":{"node-LatLon":{"lon":-1077141060,"lat":417319013}}},{"delta":{"node-LatLon":{"lon":-1077216222,"lat":417301908}}},{"delta":{"node-LatLon":{"lon":-1077291383,"lat":417284807}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417772272,"long":-1073083802}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31267}},"msgCnt":90}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":2,"serialNumber":15431,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":31267,"packetID":"000000000000024E94","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":417275428,"long":-1077311709},"name":"eastbound_I80_187.2_209.5_SAT-0A794CC9_RC_RAWI80WRSI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1077292868,"lat":417279720}}},{"delta":{"node-LatLon":{"lon":-1077217513,"lat":417296919}}},{"delta":{"node-LatLon":{"lon":-1077142143,"lat":417314087}}},{"delta":{"node-LatLon":{"lon":-1077068049,"lat":417330933}}},{"delta":{"node-LatLon":{"lon":-1076993961,"lat":417347795}}},{"delta":{"node-LatLon":{"lon":-1076919664,"lat":417364670}}},{"delta":{"node-LatLon":{"lon":-1076845181,"lat":417381611}}},{"delta":{"node-LatLon":{"lon":-1076770688,"lat":417398531}}},{"delta":{"node-LatLon":{"lon":-1076695769,"lat":417412771}}},{"delta":{"node-LatLon":{"lon":-1076618859,"lat":417418968}}},{"delta":{"node-LatLon":{"lon":-1076541598,"lat":417424427}}},{"delta":{"node-LatLon":{"lon":-1076464105,"lat":417429921}}},{"delta":{"node-LatLon":{"lon":-1076386610,"lat":417435404}}},{"delta":{"node-LatLon":{"lon":-1076309252,"lat":417440926}}},{"delta":{"node-LatLon":{"lon":-1076231889,"lat":417446401}}},{"delta":{"node-LatLon":{"lon":-1076155879,"lat":417451762}}},{"delta":{"node-LatLon":{"lon":-1076081223,"lat":417457006}}},{"delta":{"node-LatLon":{"lon":-1076006571,"lat":417462290}}},{"delta":{"node-LatLon":{"lon":-1075928925,"lat":417467718}}},{"delta":{"node-LatLon":{"lon":-1075851297,"lat":417473296}}},{"delta":{"node-LatLon":{"lon":-1075775135,"lat":417482757}}},{"delta":{"node-LatLon":{"lon":-1075701404,"lat":417498056}}},{"delta":{"node-LatLon":{"lon":-1075627970,"lat":417514175}}},{"delta":{"node-LatLon":{"lon":-1075551546,"lat":417530959}}},{"delta":{"node-LatLon":{"lon":-1075475121,"lat":417547742}}},{"delta":{"node-LatLon":{"lon":-1075399612,"lat":417564374}}},{"delta":{"node-LatLon":{"lon":-1075324973,"lat":417580735}}},{"delta":{"node-LatLon":{"lon":-1075250327,"lat":417597082}}},{"delta":{"node-LatLon":{"lon":-1075175762,"lat":417613457}}},{"delta":{"node-LatLon":{"lon":-1075101172,"lat":417629774}}},{"delta":{"node-LatLon":{"lon":-1075026992,"lat":417646108}}},{"delta":{"node-LatLon":{"lon":-1074953281,"lat":417662619}}},{"delta":{"node-LatLon":{"lon":-1074879569,"lat":417679134}}},{"delta":{"node-LatLon":{"lon":-1074805891,"lat":417695635}}},{"delta":{"node-LatLon":{"lon":-1074732212,"lat":417712139}}},{"delta":{"node-LatLon":{"lon":-1074658253,"lat":417728674}}},{"delta":{"node-LatLon":{"lon":-1074584060,"lat":417745361}}},{"delta":{"node-LatLon":{"lon":-1074509845,"lat":417761996}}},{"delta":{"node-LatLon":{"lon":-1074435611,"lat":417778588}}},{"delta":{"node-LatLon":{"lon":-1074361397,"lat":417795237}}},{"delta":{"node-LatLon":{"lon":-1074287484,"lat":417811796}}},{"delta":{"node-LatLon":{"lon":-1074213869,"lat":417828258}}},{"delta":{"node-LatLon":{"lon":-1074140155,"lat":417844465}}},{"delta":{"node-LatLon":{"lon":-1074062164,"lat":417855879}}},{"delta":{"node-LatLon":{"lon":-1073983504,"lat":417864579}}},{"delta":{"node-LatLon":{"lon":-1073906783,"lat":417873095}}},{"delta":{"node-LatLon":{"lon":-1073831510,"lat":417877605}}},{"delta":{"node-LatLon":{"lon":-1073756373,"lat":417872063}}},{"delta":{"node-LatLon":{"lon":-1073681801,"lat":417855903}}},{"delta":{"node-LatLon":{"lon":-1073609122,"lat":417835248}}},{"delta":{"node-LatLon":{"lon":-1073536658,"lat":417814684}}},{"delta":{"node-LatLon":{"lon":-1073464445,"lat":417794142}}},{"delta":{"node-LatLon":{"lon":-1073392087,"lat":417773900}}},{"delta":{"node-LatLon":{"lon":-1073317135,"lat":417760222}}},{"delta":{"node-LatLon":{"lon":-1073240133,"lat":417756689}}},{"delta":{"node-LatLon":{"lon":-1073163130,"lat":417761557}}},{"delta":{"node-LatLon":{"lon":-1073105417,"lat":417766002}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":417275428,"long":-1077311709}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":5906}},{"item":{"itis":5385}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":31267}},"msgCnt":78}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":1,"serialNumber":15430,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.851Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":22692,"packetID":"00000000000006AD92","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416344087,"long":-1082586926},"name":"westbound_I80_142.17_158.55_SAT-44ADF832_RC_PDI80ED","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1082605867,"lat":416341147}}},{"delta":{"node-LatLon":{"lon":-1082643762,"lat":416335317}}},{"delta":{"node-LatLon":{"lon":-1082719537,"lat":416323607}}},{"delta":{"node-LatLon":{"lon":-1082795332,"lat":416311823}}},{"delta":{"node-LatLon":{"lon":-1082871219,"lat":416300396}}},{"delta":{"node-LatLon":{"lon":-1082948412,"lat":416300333}}},{"delta":{"node-LatLon":{"lon":-1083025592,"lat":416303069}}},{"delta":{"node-LatLon":{"lon":-1083102774,"lat":416305783}}},{"delta":{"node-LatLon":{"lon":-1083179715,"lat":416308441}}},{"delta":{"node-LatLon":{"lon":-1083256650,"lat":416311187}}},{"delta":{"node-LatLon":{"lon":-1083333670,"lat":416313866}}},{"delta":{"node-LatLon":{"lon":-1083410768,"lat":416316579}}},{"delta":{"node-LatLon":{"lon":-1083487872,"lat":416319193}}},{"delta":{"node-LatLon":{"lon":-1083564905,"lat":416322423}}},{"delta":{"node-LatLon":{"lon":-1083641683,"lat":416328142}}},{"delta":{"node-LatLon":{"lon":-1083718587,"lat":416332876}}},{"delta":{"node-LatLon":{"lon":-1083795496,"lat":416337572}}},{"delta":{"node-LatLon":{"lon":-1083872405,"lat":416342269}}},{"delta":{"node-LatLon":{"lon":-1083949300,"lat":416347096}}},{"delta":{"node-LatLon":{"lon":-1084026064,"lat":416352984}}},{"delta":{"node-LatLon":{"lon":-1084103063,"lat":416357400}}},{"delta":{"node-LatLon":{"lon":-1084180198,"lat":416361177}}},{"delta":{"node-LatLon":{"lon":-1084257244,"lat":416365879}}},{"delta":{"node-LatLon":{"lon":-1084326673,"lat":416370105}}},{"delta":{"node-LatLon":{"lon":-1084396100,"lat":416374353}}},{"delta":{"node-LatLon":{"lon":-1084469893,"lat":416378867}}},{"delta":{"node-LatLon":{"lon":-1084548056,"lat":416383611}}},{"delta":{"node-LatLon":{"lon":-1084626220,"lat":416388347}}},{"delta":{"node-LatLon":{"lon":-1084703702,"lat":416393060}}},{"delta":{"node-LatLon":{"lon":-1084781188,"lat":416397734}}},{"delta":{"node-LatLon":{"lon":-1084859010,"lat":416402450}}},{"delta":{"node-LatLon":{"lon":-1084937168,"lat":416407197}}},{"delta":{"node-LatLon":{"lon":-1085015328,"lat":416411930}}},{"delta":{"node-LatLon":{"lon":-1085093024,"lat":416416612}}},{"delta":{"node-LatLon":{"lon":-1085170718,"lat":416421321}}},{"delta":{"node-LatLon":{"lon":-1085248418,"lat":416425954}}},{"delta":{"node-LatLon":{"lon":-1085326100,"lat":416430747}}},{"delta":{"node-LatLon":{"lon":-1085403806,"lat":416435322}}},{"delta":{"node-LatLon":{"lon":-1085482142,"lat":416440051}}},{"delta":{"node-LatLon":{"lon":-1085560481,"lat":416444752}}},{"delta":{"node-LatLon":{"lon":-1085638702,"lat":416449395}}},{"delta":{"node-LatLon":{"lon":-1085716794,"lat":416454065}}},{"delta":{"node-LatLon":{"lon":-1085775366,"lat":416457555}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0000000000011000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416344087,"long":-1082586926}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":22692}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} +{"metadata":{"securityResultCode":"success","recordGeneratedBy":"TMC_VIA_SAT","receivedMessageDetails":{"locationData":{"elevation":2080,"heading":79,"latitude":41.1022969,"speed":22.06,"longitude":-105.0484435},"rxSource":"SAT"},"schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":15429,"streamId":"801780cb-d91d-444b-8f4d-9c44fe27f5ea","bundleSize":166,"bundleId":77},"sanitized":false,"recordGeneratedAt":"2019-01-22T22:27:06.751Z","recordType":"rxMsg","logFileName":"rxMsg_TIM_GeneratedBy_TMC_VIA_SAT.gz","odeReceivedAt":"2019-04-09T18:11:18.996Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":22692,"packetID":"000000000000086861","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":416455490,"long":-1085800440},"name":"eastbound_I80_142.17_158.55_SAT-1C6D23BF_RC_PDI80EI","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1085780958,"lat":416453533}}},{"delta":{"node-LatLon":{"lon":-1085722182,"lat":416449943}}},{"delta":{"node-LatLon":{"lon":-1085643804,"lat":416445230}}},{"delta":{"node-LatLon":{"lon":-1085565424,"lat":416440540}}},{"delta":{"node-LatLon":{"lon":-1085487043,"lat":416435869}}},{"delta":{"node-LatLon":{"lon":-1085408668,"lat":416431146}}},{"delta":{"node-LatLon":{"lon":-1085330293,"lat":416426421}}},{"delta":{"node-LatLon":{"lon":-1085251916,"lat":416421727}}},{"delta":{"node-LatLon":{"lon":-1085173902,"lat":416416997}}},{"delta":{"node-LatLon":{"lon":-1085096242,"lat":416412330}}},{"delta":{"node-LatLon":{"lon":-1085018585,"lat":416407636}}},{"delta":{"node-LatLon":{"lon":-1084940663,"lat":416402897}}},{"delta":{"node-LatLon":{"lon":-1084862741,"lat":416398163}}},{"delta":{"node-LatLon":{"lon":-1084784815,"lat":416393472}}},{"delta":{"node-LatLon":{"lon":-1084706889,"lat":416388787}}},{"delta":{"node-LatLon":{"lon":-1084628972,"lat":416384031}}},{"delta":{"node-LatLon":{"lon":-1084551057,"lat":416379343}}},{"delta":{"node-LatLon":{"lon":-1084473154,"lat":416374560}}},{"delta":{"node-LatLon":{"lon":-1084399541,"lat":416370085}}},{"delta":{"node-LatLon":{"lon":-1084330227,"lat":416365845}}},{"delta":{"node-LatLon":{"lon":-1084260912,"lat":416361623}}},{"delta":{"node-LatLon":{"lon":-1084184275,"lat":416356906}}},{"delta":{"node-LatLon":{"lon":-1084107548,"lat":416353136}}},{"delta":{"node-LatLon":{"lon":-1084030065,"lat":416348811}}},{"delta":{"node-LatLon":{"lon":-1083951951,"lat":416342842}}},{"delta":{"node-LatLon":{"lon":-1083873709,"lat":416337915}}},{"delta":{"node-LatLon":{"lon":-1083796972,"lat":416333186}}},{"delta":{"node-LatLon":{"lon":-1083720234,"lat":416328459}}},{"delta":{"node-LatLon":{"lon":-1083643497,"lat":416323733}}},{"delta":{"node-LatLon":{"lon":-1083566759,"lat":416319020}}},{"delta":{"node-LatLon":{"lon":-1083489868,"lat":416316067}}},{"delta":{"node-LatLon":{"lon":-1083413019,"lat":416313460}}},{"delta":{"node-LatLon":{"lon":-1083336178,"lat":416310750}}},{"delta":{"node-LatLon":{"lon":-1083259199,"lat":416308063}}},{"delta":{"node-LatLon":{"lon":-1083182086,"lat":416305377}}},{"delta":{"node-LatLon":{"lon":-1083104978,"lat":416302622}}},{"delta":{"node-LatLon":{"lon":-1083028061,"lat":416299895}}},{"delta":{"node-LatLon":{"lon":-1082951147,"lat":416297144}}},{"delta":{"node-LatLon":{"lon":-1082873751,"lat":416296812}}},{"delta":{"node-LatLon":{"lon":-1082797210,"lat":416308158}}},{"delta":{"node-LatLon":{"lon":-1082720795,"lat":416320017}}},{"delta":{"node-LatLon":{"lon":-1082645377,"lat":416331711}}},{"delta":{"node-LatLon":{"lon":-1082607675,"lat":416337584}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":"0001100000000000"}},"durationTime":32000,"doNotUse3":0,"doNotUse4":0,"startYear":2019,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":416455490,"long":-1085800440}}},"priority":5,"content":{"advisory":{"SEQUENCE":{"item":{"itis":5895}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":22692}},"msgCnt":20}}}},"dataType":"TravelerInformation"}} diff --git a/jpo-ode-svcs/src/test/resources/sdwRequest.json b/jpo-ode-svcs/src/test/resources/sdwRequest.json index 321b36514..5542d12bf 100644 --- a/jpo-ode-svcs/src/test/resources/sdwRequest.json +++ b/jpo-ode-svcs/src/test/resources/sdwRequest.json @@ -24,7 +24,7 @@ { "startDateTime": "2020-04-30T14:23:59.497Z", "durationTime": 1440, - "notUsed": "1", + "doNotUse1": "1", "frameType": "advisory", "msgId": { "roadSignID": { @@ -37,7 +37,7 @@ } }, "priority": "5", - "notUsed1": "0", + "doNotUse2": "0", "regions": [ { "name": "I_I 25_SAT-1CEE1793", From 247c20b50db99de02ca6304ad8ca439e741a99fe Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 10:49:45 -0700 Subject: [PATCH 076/264] Updated docs to comply with J2735 2024 --- docs/ODESwagger.yaml | 4 ++-- docs/index.html | 4 ++-- docs/timEndpointCurl.sh | 4 ++-- docs/timEndpointPython.py | 2 +- .../test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/ODESwagger.yaml b/docs/ODESwagger.yaml index 8128bd30b..399cc96ab 100644 --- a/docs/ODESwagger.yaml +++ b/docs/ODESwagger.yaml @@ -358,7 +358,7 @@ definitions: required: - sspindex properties: - notUsed: + doNotUse1: type: integer description: A short header information frameType: @@ -377,7 +377,7 @@ definitions: means forever. priority: type: integer - notUsed1: + doNotUse2: type: integer sspindex: type: integer diff --git a/docs/index.html b/docs/index.html index 444b8bbfc..01073fab3 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1303,7 +1303,7 @@ "type" : "object", "required" : [ "sspindex" ], "properties" : { - "notUsed" : { + "doNotUse1" : { "type" : "integer", "description" : "A short header information" }, @@ -1324,7 +1324,7 @@ "priority" : { "type" : "integer" }, - "notUsed1" : { + "doNotUse2" : { "type" : "integer" }, "sspindex" : { diff --git a/docs/timEndpointCurl.sh b/docs/timEndpointCurl.sh index 5c6d4f6c3..79e300215 100755 --- a/docs/timEndpointCurl.sh +++ b/docs/timEndpointCurl.sh @@ -196,8 +196,8 @@ curl -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H }] }, "content": { - "notUsed2": "0", - "notUsed3": "0", + "doNotUse3": "0", + "doNotUse4": "0", "contentType": { "advisory": [{ "ITISCodes": "268", diff --git a/docs/timEndpointPython.py b/docs/timEndpointPython.py index 2ec2afbf1..e8c880ef4 100644 --- a/docs/timEndpointPython.py +++ b/docs/timEndpointPython.py @@ -2,7 +2,7 @@ url = "http://localhost:8080/tim" -payload = "{\r\n\t\"timContent\": {\r\n\t\t\"msgcnt\": \"1\",\r\n\t\t\"timestamp\": \"op\",\r\n\t\t\"packetID\": \"op\",\r\n\t\t\"urlB\": \"op\",\r\n\t\t\"travelerDataFrame\": [{\r\n\t\t\t\"header\": {\r\n\t\t\t\t\"sspindex\": \"1\",\r\n\t\t\t\t\"travelerInfoType\": \"1\",\r\n\t\t\t\t\"msgId\": {\r\n\t\t\t\t\t\"FurtherInfoID\": \"1\",\r\n\t\t\t\t\t\"RoadSignID\": {\r\n\t\t\t\t\t\t\"position3D\": {\r\n\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\"HeadingSlice\": \"1010011010010100\",\r\n\t\t\t\t\t\t\"MUTCDCode\": \"op\",\r\n\t\t\t\t\t\t\"MsgCRC\": \"op\"\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\t\"DYear\": \"op\",\r\n\t\t\t\t\"MinuteOfTheYear\": \"0\",\r\n\t\t\t\t\"MinutesDuration\": \"0\",\r\n\t\t\t\t\"SignPriority\": \"0\"\r\n\t\t\t},\r\n\t\t\t\"region\": {\r\n\t\t\t\t\"sspindex\": \"0\",\r\n\t\t\t\t\"GeographicalPath\": [{\r\n\t\t\t\t\t\"name\": \"op\",\r\n\t\t\t\t\t\"id\": \"op\",\r\n\t\t\t\t\t\"anchor\": \"op\",\r\n\t\t\t\t\t\"laneWidth\": \"op\",\r\n\t\t\t\t\t\"diretionality\": \"op\",\r\n\t\t\t\t\t\"closedPath\": \"op\",\r\n\t\t\t\t\t\"direction\": \"op\",\r\n\t\t\t\t\t\"description\": [{\r\n\t\t\t\t\t\t\"path\": [{\r\n\t\t\t\t\t\t\t\"scale\": \"op\",\r\n\t\t\t\t\t\t\t\"offset\": [{\r\n\t\t\t\t\t\t\t\t\"xy\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"computed\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"referenceLaneID\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"offsetXaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"offsetYaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"ll\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\"geometry\": [{\r\n\t\t\t\t\t\t\t\"direction\": \"1001101100100100\",\r\n\t\t\t\t\t\t\t\"circle\": [{\r\n\t\t\t\t\t\t\t\t\"center\": [{\r\n\t\t\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"radius\": \"3\",\r\n\t\t\t\t\t\t\t\t\"units\": \"4\"\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\"oldRegion\": [{\r\n\t\t\t\t\t\t\t\"direction\": \"1001101100100100\",\r\n\t\t\t\t\t\t\t\"area\": [{\r\n\t\t\t\t\t\t\t\t\"shapePointSet\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"computed\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"referenceLaneID\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"offsetXaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"offsetYaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"circle\": [{\r\n\t\t\t\t\t\t\t\t\t\"center\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"radius\": \"3\",\r\n\t\t\t\t\t\t\t\t\t\"units\": \"4\"\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"regionPointSet\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodeList\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"xOffset\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"yOffset\": \"1\"\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}]\r\n\t\t\t\t\t}]\r\n\t\t\t\t}]\r\n\t\t\t},\r\n\t\t\t\"content\": {\r\n\t\t\t\t\"notUsed2\": \"0\",\r\n\t\t\t\t\"notUsed3\": \"0\",\r\n\t\t\t\t\"contentType\": {\r\n\t\t\t\t\t\"advisory\": [{\r\n\t\t\t\t\t\t\"ITISCodes\": \"268\",\r\n\t\t\t\t\t\t\"ITIStext\": \"Speed Limit\"\r\n\t\t\t\t\t} ],\r\n\t\t\t\t\t\"workZone\": [],\r\n\t\t\t\t\t\"genericSign\": [],\r\n\t\t\t\t\t\"speedLimit\": [],\r\n\t\t\t\t\t\"exitService\": []\r\n\t\t\t\t},\r\n\t\t\t\t\"URL-Short\": \"op\",\r\n\t\t\t\t\"regional\": \"op\"\r\n\t\t\t}\r\n\t\t}],\r\n\t\t\"regional\": \"op\"\r\n\t},\r\n\t\"RSUs\": [{\r\n\t\t\"target\": \"127.0.0.1\",\r\n\t\t\"username\": \"v3user\",\r\n\t\t\"password\": \"password\",\r\n\t\t\"retries\": \"1\",\r\n\t\t\"timeout\": \"2000\"\r\n\t}], \r\n\t\"snmp\": {\r\n\t\t\"rsuid\": \"8300\",\r\n\t\t\"msgid\": \"31\",\r\n\t\t\"mode\": \"1\",\r\n\t\t\"channel\": \"178\",\r\n\t\t\"interval\": \"1\",\r\n\t\t\"deliverystart\": \"010114111530\",\r\n\t\t\"deliverystop\": \"010114130000\",\r\n\t\t\"enable\": \"1\",\r\n\t\t\"status\": \"4\"\r\n\t}\r\n}" +payload = "{\r\n\t\"timContent\": {\r\n\t\t\"msgcnt\": \"1\",\r\n\t\t\"timestamp\": \"op\",\r\n\t\t\"packetID\": \"op\",\r\n\t\t\"urlB\": \"op\",\r\n\t\t\"travelerDataFrame\": [{\r\n\t\t\t\"header\": {\r\n\t\t\t\t\"sspindex\": \"1\",\r\n\t\t\t\t\"travelerInfoType\": \"1\",\r\n\t\t\t\t\"msgId\": {\r\n\t\t\t\t\t\"FurtherInfoID\": \"1\",\r\n\t\t\t\t\t\"RoadSignID\": {\r\n\t\t\t\t\t\t\"position3D\": {\r\n\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\"HeadingSlice\": \"1010011010010100\",\r\n\t\t\t\t\t\t\"MUTCDCode\": \"op\",\r\n\t\t\t\t\t\t\"MsgCRC\": \"op\"\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\t\"DYear\": \"op\",\r\n\t\t\t\t\"MinuteOfTheYear\": \"0\",\r\n\t\t\t\t\"MinutesDuration\": \"0\",\r\n\t\t\t\t\"SignPriority\": \"0\"\r\n\t\t\t},\r\n\t\t\t\"region\": {\r\n\t\t\t\t\"sspindex\": \"0\",\r\n\t\t\t\t\"GeographicalPath\": [{\r\n\t\t\t\t\t\"name\": \"op\",\r\n\t\t\t\t\t\"id\": \"op\",\r\n\t\t\t\t\t\"anchor\": \"op\",\r\n\t\t\t\t\t\"laneWidth\": \"op\",\r\n\t\t\t\t\t\"diretionality\": \"op\",\r\n\t\t\t\t\t\"closedPath\": \"op\",\r\n\t\t\t\t\t\"direction\": \"op\",\r\n\t\t\t\t\t\"description\": [{\r\n\t\t\t\t\t\t\"path\": [{\r\n\t\t\t\t\t\t\t\"scale\": \"op\",\r\n\t\t\t\t\t\t\t\"offset\": [{\r\n\t\t\t\t\t\t\t\t\"xy\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"computed\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"referenceLaneID\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"offsetXaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"offsetYaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"ll\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\"geometry\": [{\r\n\t\t\t\t\t\t\t\"direction\": \"1001101100100100\",\r\n\t\t\t\t\t\t\t\"circle\": [{\r\n\t\t\t\t\t\t\t\t\"center\": [{\r\n\t\t\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"radius\": \"3\",\r\n\t\t\t\t\t\t\t\t\"units\": \"4\"\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\"oldRegion\": [{\r\n\t\t\t\t\t\t\t\"direction\": \"1001101100100100\",\r\n\t\t\t\t\t\t\t\"area\": [{\r\n\t\t\t\t\t\t\t\t\"shapePointSet\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodes\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"delta\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL1\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL2\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL3\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL4\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL5\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\t\"node-LL6\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lon\": \"20\",\r\n\t\t\t\t\t\t\t\t\t\t\t\t\"lat\": \"21\"\r\n\t\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"attributes\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"computed\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"referenceLaneID\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"offsetXaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\t\"offsetYaxis\": [{\r\n\t\t\t\t\t\t\t\t\t\t\t\"small\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\t\"large\": \"1\"\r\n\t\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"circle\": [{\r\n\t\t\t\t\t\t\t\t\t\"center\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"latitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"longitude\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"elevation\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"regional\": \"op\"\r\n\t\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\t\"radius\": \"3\",\r\n\t\t\t\t\t\t\t\t\t\"units\": \"4\"\r\n\t\t\t\t\t\t\t\t}],\r\n\t\t\t\t\t\t\t\t\"regionPointSet\": [{\r\n\t\t\t\t\t\t\t\t\t\"nodeList\": [{\r\n\t\t\t\t\t\t\t\t\t\t\"xOffset\": \"1\",\r\n\t\t\t\t\t\t\t\t\t\t\"yOffset\": \"1\"\r\n\t\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t\t}]\r\n\t\t\t\t\t\t}]\r\n\t\t\t\t\t}]\r\n\t\t\t\t}]\r\n\t\t\t},\r\n\t\t\t\"content\": {\r\n\t\t\t\t\"doNotUse3\": \"0\",\r\n\t\t\t\t\"doNotUse4\": \"0\",\r\n\t\t\t\t\"contentType\": {\r\n\t\t\t\t\t\"advisory\": [{\r\n\t\t\t\t\t\t\"ITISCodes\": \"268\",\r\n\t\t\t\t\t\t\"ITIStext\": \"Speed Limit\"\r\n\t\t\t\t\t} ],\r\n\t\t\t\t\t\"workZone\": [],\r\n\t\t\t\t\t\"genericSign\": [],\r\n\t\t\t\t\t\"speedLimit\": [],\r\n\t\t\t\t\t\"exitService\": []\r\n\t\t\t\t},\r\n\t\t\t\t\"URL-Short\": \"op\",\r\n\t\t\t\t\"regional\": \"op\"\r\n\t\t\t}\r\n\t\t}],\r\n\t\t\"regional\": \"op\"\r\n\t},\r\n\t\"RSUs\": [{\r\n\t\t\"target\": \"127.0.0.1\",\r\n\t\t\"username\": \"v3user\",\r\n\t\t\"password\": \"password\",\r\n\t\t\"retries\": \"1\",\r\n\t\t\"timeout\": \"2000\"\r\n\t}], \r\n\t\"snmp\": {\r\n\t\t\"rsuid\": \"8300\",\r\n\t\t\"msgid\": \"31\",\r\n\t\t\"mode\": \"1\",\r\n\t\t\"channel\": \"178\",\r\n\t\t\"interval\": \"1\",\r\n\t\t\"deliverystart\": \"010114111530\",\r\n\t\t\"deliverystop\": \"010114130000\",\r\n\t\t\"enable\": \"1\",\r\n\t\t\"status\": \"4\"\r\n\t}\r\n}" headers = { 'content-type': "application/json", 'cache-control': "no-cache", diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java index 9a626ccff..70419000d 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java @@ -18,7 +18,7 @@ public class OdeTimDataTest { private static final String SCHEMA_VERSION = "7"; private static final String ASN1_STRING = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e"; - private static final String json = String.format("{\"metadata\":{\"securityResultCode\":\"\",\"recordGeneratedBy\":\"RSU\",\"schemaVersion\":\"%s\",\"odePacketID\":\"\",\"sanitized\":\"false\",\"asn1\":\"%s\",\"recordType\":\"timMsg\",\"recordGeneratedAt\":\"\",\"maxDurationTime\":\"0\",\"odeTimStartDateTime\":\"\",\"receivedMessageDetails\":\"\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"recordId\":\"0\",\"serialNumber\":\"0\",\"streamId\":\"11ad5323-ec81-4694-8cd0-eb88ca08728e\",\"bundleSize\":\"1\",\"bundleId\":\"0\"},\"logFileName\":\"\",\"odeReceivedAt\":\"2022-12-24T02:24:38.248417Z\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"data\":{\"MessageFrame\":{\"messageId\":\"31\",\"value\":{\"TravelerInformation\":{\"timeStamp\":\"449089\",\"packetID\":\"0000000000000BBC2B\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":{\"regions\":{\"GeographicalPath\":{\"closedPath\":{\"false\":\"\"},\"anchor\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"},\"name\":\"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456\",\"laneWidth\":\"32700\",\"directionality\":{\"both\":\"\"},\"description\":{\"path\":{\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047287423\",\"lat\":\"411264686\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047305390\",\"lat\":\"411260104\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047323629\",\"lat\":\"411256185\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047342080\",\"lat\":\"411252886\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047360706\",\"lat\":\"411250207\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047379480\",\"lat\":\"411248201\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047398354\",\"lat\":\"411246839\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047417290\",\"lat\":\"411246133\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047436246\",\"lat\":\"411245796\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047455202\",\"lat\":\"411245470\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047474159\",\"lat\":\"411245173\"}}}]}}},\"scale\":\"0\"}},\"id\":{\"id\":\"0\",\"region\":\"0\"},\"direction\":\"0000000000010000\"}},\"durationTime\":\"1440\",\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"startYear\":\"2018\",\"msgId\":{\"roadSignID\":{\"viewAngle\":\"1111111111111111\",\"mutcdCode\":{\"warning\":\"\"},\"position\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"}}},\"priority\":\"5\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"777\"}},{\"item\":{\"itis\":\"13579\"}}]}},\"url\":\"null\",\"notUsed\":\"0\",\"notUsed1\":\"0\",\"frameType\":{\"advisory\":\"\"},\"startTime\":\"448260\"}},\"msgCnt\":\"1\"}}}},\"dataType\":\"TravelerInformation\"}}", SCHEMA_VERSION, ASN1_STRING); + private static final String json = String.format("{\"metadata\":{\"securityResultCode\":\"\",\"recordGeneratedBy\":\"RSU\",\"schemaVersion\":\"%s\",\"odePacketID\":\"\",\"sanitized\":\"false\",\"asn1\":\"%s\",\"recordType\":\"timMsg\",\"recordGeneratedAt\":\"\",\"maxDurationTime\":\"0\",\"odeTimStartDateTime\":\"\",\"receivedMessageDetails\":\"\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"recordId\":\"0\",\"serialNumber\":\"0\",\"streamId\":\"11ad5323-ec81-4694-8cd0-eb88ca08728e\",\"bundleSize\":\"1\",\"bundleId\":\"0\"},\"logFileName\":\"\",\"odeReceivedAt\":\"2022-12-24T02:24:38.248417Z\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"data\":{\"MessageFrame\":{\"messageId\":\"31\",\"value\":{\"TravelerInformation\":{\"timeStamp\":\"449089\",\"packetID\":\"0000000000000BBC2B\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":{\"regions\":{\"GeographicalPath\":{\"closedPath\":{\"false\":\"\"},\"anchor\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"},\"name\":\"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456\",\"laneWidth\":\"32700\",\"directionality\":{\"both\":\"\"},\"description\":{\"path\":{\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047287423\",\"lat\":\"411264686\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047305390\",\"lat\":\"411260104\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047323629\",\"lat\":\"411256185\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047342080\",\"lat\":\"411252886\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047360706\",\"lat\":\"411250207\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047379480\",\"lat\":\"411248201\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047398354\",\"lat\":\"411246839\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047417290\",\"lat\":\"411246133\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047436246\",\"lat\":\"411245796\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047455202\",\"lat\":\"411245470\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047474159\",\"lat\":\"411245173\"}}}]}}},\"scale\":\"0\"}},\"id\":{\"id\":\"0\",\"region\":\"0\"},\"direction\":\"0000000000010000\"}},\"durationTime\":\"1440\",\"doNotUse3\":\"0\",\"doNotUse4\":\"0\",\"startYear\":\"2018\",\"msgId\":{\"roadSignID\":{\"viewAngle\":\"1111111111111111\",\"mutcdCode\":{\"warning\":\"\"},\"position\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"}}},\"priority\":\"5\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"777\"}},{\"item\":{\"itis\":\"13579\"}}]}},\"url\":\"null\",\"doNotUse1\":\"0\",\"doNotUse2\":\"0\",\"frameType\":{\"advisory\":\"\"},\"startTime\":\"448260\"}},\"msgCnt\":\"1\"}}}},\"dataType\":\"TravelerInformation\"}}", SCHEMA_VERSION, ASN1_STRING); // // Note that OdeTimData does not have annotations to support deserialization, so serialization/deserialization is not tested here. From 092c9a5586dd56029c5c53eca817817ed25d409c Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 11:10:13 -0700 Subject: [PATCH 077/264] Replaced older fields with doNotUseX to comply with J2735 2024 --- .../TIM_BroadcastSampleOutput.json | 24 ++++++++-------- .../archive/TimTestGeometry.json | 4 +-- .../archive/TimTestPath_LL.json | 4 +-- .../archive/TimTestPath_XY.json | 4 +-- .../archive/TimTestoldRegion.json | 4 +-- .../tim_geometry_multi_rsu_no_sdw.json | 4 +-- .../tim_geometry_multi_rsu_sdw.json | 4 +-- ...tim_path_xy_node_any_multi_rsu_no_sdw.json | 4 +-- ..._path_xy_node_latlon_multi_rsu_no_sdw.json | 4 +-- .../tim_path_xy_node_latlon_no_rsu_sdw.json | 4 +-- .../deprecated/tim_region_multiRSU.json | 4 +-- .../deprecated/tim_region_singleRSU.json | 4 +-- .../tim_region_singleRSU_hexCRC.json | 4 +-- .../tim_path_LL_single_rsu_no_sdw.json | 4 +-- .../tim_path_multiRSU_hexCRC.json | 4 +-- .../tim_path_singleRSU.json | 4 +-- ...im_path_xy_node_any_single_rsu_no_sdw.json | 4 +-- docs/ODESwagger.yaml | 4 +-- docs/index.html | 4 +-- ...lerMessageFromHumanToAsnConverterTest.java | 28 +++++++++---------- .../traveler/TimDepositControllerTest.java | 2 +- .../ode/traveler/TimTransmogrifierTest.java | 4 +-- .../src/test/resources/sdwRequest.json | 4 +-- .../timRequestContainingCircleGeometry.json | 6 ++-- 24 files changed, 70 insertions(+), 70 deletions(-) diff --git a/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json b/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json index 745b6473b..29aa96ce0 100644 --- a/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json +++ b/data/TIM_Message_Testing_Files/TIM_BroadcastSampleOutput.json @@ -1,24 +1,24 @@ {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":29,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":29},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:39.058Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"DE9AAC79"},"requestID":"DE9AAC79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":29,"recordId":0,"serialNumber":29},"odeReceivedAt":"2019-03-12T19:50:39.057Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":29,"recordId":0,"serialNumber":29},"odeReceivedAt":"2019-03-12T19:50:39.057Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["250"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":28,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":28},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:38.120Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":19595894},"requestID":19595894,"groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":28,"recordId":0,"serialNumber":28},"odeReceivedAt":"2019-03-12T19:50:38.118Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":28,"recordId":0,"serialNumber":28},"odeReceivedAt":"2019-03-12T19:50:38.118Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["250"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":27,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":27},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:37.242Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":250}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"C7062151"},"requestID":"C7062151","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":27,"recordId":0,"serialNumber":27},"odeReceivedAt":"2019-03-12T19:50:37.240Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["250"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":27,"recordId":0,"serialNumber":27},"odeReceivedAt":"2019-03-12T19:50:37.240Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["250"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":26,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":26},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:36.350Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":411139330,"long":-1048507720}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":155120}},"msgCnt":1}}}}}}},"startTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"stopTime":{"month":0,"hour":31,"year":0,"day":0,"minute":60},"distType":"02","asdmType":2,"asdmID":"C064E753"},"requestID":"C064E753","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":26,"recordId":0,"serialNumber":26},"odeReceivedAt":"2019-03-12T19:50:36.348Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.113933,"longitude":-104.850772},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-04-18T11:20-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":26,"recordId":0,"serialNumber":26},"odeReceivedAt":"2019-03-12T19:50:36.348Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.113933,"longitude":-104.850772},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-04-18T11:20-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"doNotUse4":1,"doNotUse3":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":25,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":25},"sanitized":false,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","odeReceivedAt":"2019-03-12T19:50:35.499Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":155198,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-LatLon":{"lon":-1050473550,"lat":405724290}}},{"delta":{"node-LatLon":{"lon":-1050468440,"lat":405722280}}},{"delta":{"node-LatLon":{"lon":-1050465900,"lat":405721130}}},{"delta":{"node-LatLon":{"lon":-1050462430,"lat":405719100}}},{"delta":{"node-LatLon":{"lon":-1050459360,"lat":405716750}}},{"delta":{"node-LatLon":{"lon":-1050456740,"lat":405714220}}},{"delta":{"node-LatLon":{"lon":-1050454500,"lat":405711310}}},{"delta":{"node-LatLon":{"lon":-1050452350,"lat":405707240}}},{"delta":{"node-LatLon":{"lon":-1050451130,"lat":405702930}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":25,"recordId":0,"serialNumber":25},"odeReceivedAt":"2019-03-12T19:50:35.497Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":25,"recordId":0,"serialNumber":25},"odeReceivedAt":"2019-03-12T19:50:35.497Z","schemaVersion":6,"recordGeneratedAt":"2018-04-18T18:38:52.914Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-04-18T18:38:52.914Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-LatLon","nodeLat":40.572429,"nodeLong":-105.047355},{"delta":"node-LatLon","nodeLat":40.572228,"nodeLong":-105.046844},{"delta":"node-LatLon","nodeLat":40.572113,"nodeLong":-105.04659},{"delta":"node-LatLon","nodeLat":40.57191,"nodeLong":-105.046243},{"delta":"node-LatLon","nodeLat":40.571675,"nodeLong":-105.045936},{"delta":"node-LatLon","nodeLat":40.571422,"nodeLong":-105.045674},{"delta":"node-LatLon","nodeLat":40.571131,"nodeLong":-105.04545},{"delta":"node-LatLon","nodeLat":40.570724,"nodeLong":-105.045235},{"delta":"node-LatLon","nodeLat":40.570293,"nodeLong":-105.045113},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"doNotUse4":1,"doNotUse3":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":24,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":24},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:34.670Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LL1":{"lon":2047,"lat":-2048}}},{"delta":{"node-LL2":{"lon":8191,"lat":-8192}}},{"delta":{"node-LL3":{"lon":32767,"lat":-32768}}},{"delta":{"node-LL4":{"lon":131071,"lat":-131072}}},{"delta":{"node-LL5":{"lon":2097151,"lat":-2097152}}},{"delta":{"node-LL6":{"lon":8388607,"lat":-8388608}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":24,"recordId":0,"serialNumber":24},"odeReceivedAt":"2019-03-12T19:50:34.666Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":24,"recordId":0,"serialNumber":24},"odeReceivedAt":"2019-03-12T19:50:34.666Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":23,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":23},"sanitized":false,"recordGeneratedAt":"2018-06-11T16:00:00Z","odeReceivedAt":"2019-03-12T19:50:33.824Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":232800,"packetID":"0000002316f1b0eed3","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"lat":405730680,"long":-1050490160},"name":"southbound_Timberline_20_30_RSU-192.168.0.100","laneWidth":32700,"directionality":{"both":""},"description":{"path":{"offset":{"xy":{"nodes":{"NodeXY":[{"delta":{"node-XY1":{"x":-512,"y":511}}},{"delta":{"node-XY2":{"x":-1024,"y":1023}}},{"delta":{"node-XY3":{"x":-2048,"y":2047}}},{"delta":{"node-XY4":{"x":-4096,"y":4095}}},{"delta":{"node-XY5":{"x":-8192,"y":8191}}},{"delta":{"node-XY6":{"x":-32768,"y":32767}}},{"delta":{"node-LatLon":{"lon":-1050450870,"lat":405698480}}}]}}},"scale":0}},"id":{"id":0,"region":0},"direction":1111111111111111}},"durationTime":2000,"doNotUse3":0,"doNotUse4":0,"startYear":2018,"msgId":{"roadSignID":{"viewAngle":1111111111111111,"mutcdCode":{"warning":""},"position":{"lat":405730680,"long":-1050490160}}},"priority":5,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":232800}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":23,"recordId":0,"serialNumber":23},"odeReceivedAt":"2019-03-12T19:50:33.823Z","schemaVersion":6,"recordGeneratedAt":"2018-06-11T16:00:00Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-06-11T16:00:00.000Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-XY","x":-5.12,"y":5.11},{"delta":"node-XY","x":-10.24,"y":10.23},{"delta":"node-XY","x":-20.48,"y":20.47},{"delta":"node-XY","x":-40.96,"y":40.95},{"delta":"node-XY","x":-81.92,"y":81.91},{"delta":"node-XY","x":-327.68,"y":327.67},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"sspMsgTypes":1,"sspMsgContent":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":23,"recordId":0,"serialNumber":23},"odeReceivedAt":"2019-03-12T19:50:33.823Z","schemaVersion":6,"recordGeneratedAt":"2018-06-11T16:00:00Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2018-06-11T16:00:00.000Z","packetID":"0000002316f1b0eed3","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":40.573068,"longitude":-105.049016},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startDateTime":"2018-06-11T10:00-06:00","durationTime":2000,"priority":5,"doNotUse2":0,"regions":[{"name":"southbound_Timberline_20_30_RSU-192.168.0.100","regulatorID":0,"segmentID":0,"anchorPosition":{"latitude":40.573068,"longitude":-105.049016},"laneWidth":327,"directionality":"3","closedPath":false,"direction":"1111111111111111","description":"path","path":{"scale":0,"type":"xy","nodes":[{"delta":"node-XY","x":-5.12,"y":5.11},{"delta":"node-XY","x":-10.24,"y":10.23},{"delta":"node-XY","x":-20.48,"y":20.47},{"delta":"node-XY","x":-40.96,"y":40.95},{"delta":"node-XY","x":-81.92,"y":81.91},{"delta":"node-XY","x":-327.68,"y":327.67},{"delta":"node-LatLon","nodeLat":40.569848,"nodeLong":-105.045087}]}}],"doNotUse4":1,"doNotUse3":1,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":22,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":22},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:32.883Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"B5DF2B65"},"requestID":"B5DF2B65","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":22,"recordId":0,"serialNumber":22},"odeReceivedAt":"2019-03-12T19:50:32.879Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":22,"recordId":0,"serialNumber":22},"odeReceivedAt":"2019-03-12T19:50:32.879Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["513"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":21,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":21},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:31.737Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":31024,"lat":14506}}},{"delta":{"node-LL3":{"lon":30974,"lat":14568}}},{"delta":{"node-LL3":{"lon":30983,"lat":14559}}},{"delta":{"node-LL3":{"lon":30980,"lat":14563}}},{"delta":{"node-LL3":{"lon":30982,"lat":14562}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"ABCD","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":{"item":{"itis":513}}}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"62048F79"},"requestID":"62048F79","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":21,"recordId":0,"serialNumber":21},"odeReceivedAt":"2019-03-12T19:50:31.733Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["513"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":21,"recordId":0,"serialNumber":21},"odeReceivedAt":"2019-03-12T19:50:31.733Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"ABCD"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014506,"nodeLong":0.0031024},{"delta":"node-LL3","nodeLat":0.0014568,"nodeLong":0.0030974},{"delta":"node-LL3","nodeLat":0.0014559,"nodeLong":0.0030983},{"delta":"node-LL3","nodeLat":0.0014563,"nodeLong":0.0030980},{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982}]}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["513"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":20,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":20},"sanitized":false,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","odeReceivedAt":"2019-03-12T19:50:30.318Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":309505,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":20207,"lat":412500807,"long":-1110093847},"name":"Testing TIM","laneWidth":700,"directionality":{"both":""},"description":{"path":{"offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL3":{"lon":30982,"lat":14562}}},{"delta":{"node-LatLon":{"lon":-1110093847,"lat":412500807}}}]}}},"scale":0}},"id":{"id":33,"region":0},"direction":"0000000000001010"}},"durationTime":1,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":308065}},"msgCnt":1}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":20,"recordId":0,"serialNumber":20},"odeReceivedAt":"2019-03-12T19:50:30.317Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":20,"recordId":0,"serialNumber":20},"odeReceivedAt":"2019-03-12T19:50:30.317Z","schemaVersion":6,"recordGeneratedAt":"2017-08-03T22:25:36.297Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL3","nodeLat":0.0014562,"nodeLong":0.0030982},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":19,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":19},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:28.990Z"},"payload":{"data":{"AdvisorySituationData":{"recordID":"00000000","timeToLive":3,"serviceRegion":{"nwCorner":{"lat":449984590,"long":-1110408170},"seCorner":{"lat":411046740,"long":-1041113120}},"asdmDetails":{"advisoryMessage":{"Ieee1609Dot2Data":{"protocolVersion":3,"content":{"unsecuredData":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}}}}},"startTime":{"month":6,"hour":17,"year":2017,"day":1,"minute":47},"stopTime":{"month":1,"hour":17,"year":2018,"day":1,"minute":47},"distType":"03","asdmType":2,"asdmID":"6D596E08"},"requestID":"6D596E08","groupID":"00000000","dialogID":156,"seqID":5}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":19,"recordId":0,"serialNumber":19},"odeReceivedAt":"2019-03-12T19:50:28.988Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"sdw":{"serviceRegion":{"nwCorner":{"latitude":44.998459,"longitude":-111.040817},"seCorner":{"latitude":41.104674,"longitude":-104.111312}},"ttl":"oneweek"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":19,"recordId":0,"serialNumber":19},"odeReceivedAt":"2019-03-12T19:50:28.988Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} {"metadata":{"request":{"ode":{"verb":"POST","version":3},"rsus":{"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuRetries":0,"rsuTimeout":2000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuRetries":1,"rsuTimeout":1000,"rsuPassword":"*","rsuIndex":10}]},"snmp":{"mode":1,"deliverystop":"2018-01-01T17:47:11-05:15","rsuid":"00000083","deliverystart":"2017-06-01T17:47:11-05:00","enable":1,"channel":178,"msgid":31,"interval":2,"status":4}},"recordGeneratedBy":"TMC","schemaVersion":6,"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"recordId":0,"serialNumber":18,"streamId":"162a21ba-bd99-4225-ac9d-b3dc66d02439","bundleSize":1,"bundleId":18},"sanitized":false,"recordGeneratedAt":"2017-03-13T06:07:11Z","odeReceivedAt":"2019-03-12T19:50:26.827Z"},"payload":{"data":{"MessageFrame":{"messageId":31,"value":{"TravelerInformation":{"timeStamp":102607,"packetID":"EC9C236B0000000000","urlB":null,"dataFrames":{"TravelerDataFrame":{"regions":{"GeographicalPath":{"closedPath":{"false":""},"anchor":{"elevation":9171,"lat":416784730,"long":-1087827750},"name":"bob","laneWidth":700,"directionality":{"both":""},"description":{"geometry":{"extent":1,"laneWidth":3300,"circle":{"center":{"elevation":9171,"lat":416784730,"long":-1087827750},"units":{"mile":""},"radius":15},"direction":1010101010101010}},"id":{"id":33,"region":23},"direction":1010101010101010}},"durationTime":22,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"msgId":{"roadSignID":{"crc":"0000","viewAngle":1010101010101010,"mutcdCode":{"warning":""},"position":{"elevation":9171,"lat":416784730,"long":-1087827750}}},"priority":0,"content":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":98765}}]}},"url":null,"doNotUse1":0,"doNotUse2":0,"frameType":{"advisory":""},"startTime":482327}},"msgCnt":13}}}},"dataType":"TravelerInformation"}} -{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":18,"recordId":0,"serialNumber":18},"odeReceivedAt":"2019-03-12T19:50:26.823Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"sspMsgTypes":2,"sspMsgContent":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} +{"metadata":{"request":{"ode":{"version":3,"verb":"POST"},"rsus":[{"rsuTarget":"127.0.0.1","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":0,"rsuTimeout":2000,"rsuIndex":10},{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10},{"rsuTarget":"127.0.0.3","rsuUsername":"v3user","rsuPassword":"*","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"payloadType":"us.dot.its.jpo.ode.model.OdeMsgPayload","serialId":{"streamId":"5d45936b-b91f-4bb3-992f-7b1a80a751b8","bundleSize":1,"bundleId":18,"recordId":0,"serialNumber":18},"odeReceivedAt":"2019-03-12T19:50:26.823Z","schemaVersion":6,"recordGeneratedAt":"2017-03-13T06:07:11Z","recordGeneratedBy":"TMC","sanitized":false},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage","data":{"msgCnt":13,"timeStamp":"2017-03-13T01:07:11-05:00","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-12-01T17:47:11-05:00","durationTime":22,"priority":0,"doNotUse2":0,"regions":[{"name":"bob","regulatorID":23,"segmentID":33,"anchorPosition":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"1010101010101010","description":"geometry","geometry":{"direction":"1010101010101010","extent":1,"laneWidth":33,"circle":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"radius":15,"units":"7"}}}],"doNotUse4":2,"doNotUse3":3,"content":"Advisory","items":["125","some text","250","\u002798765"],"url":"null"}]}}} diff --git a/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json b/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json index eac68adb6..076d49b4d 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestGeometry.json @@ -55,8 +55,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json b/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json index a7f08dd2d..32c080d75 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestPath_LL.json @@ -77,8 +77,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json b/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json index 493529b04..6f2f73322 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestPath_XY.json @@ -77,8 +77,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json b/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json index 0f33b4ea1..665abd8fd 100644 --- a/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json +++ b/data/TIM_Message_Testing_Files/archive/TimTestoldRegion.json @@ -86,8 +86,8 @@ } } ], - "sspMsgTypes": "0", - "sspMsgContent": "0", + "doNotUse4": "0", + "doNotUse3": "0", "content": "speedLimit", "items": [ "12579" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json index 744759cca..5d6208390 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_no_sdw.json @@ -94,8 +94,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json index 5fc554b58..8e30461d5 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_geometry_multi_rsu_sdw.json @@ -107,8 +107,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json index 9241df8c0..6c1b94a50 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_any_multi_rsu_no_sdw.json @@ -115,8 +115,8 @@ "direction": "1111111111111111" } ], - "sspMsgTypes": "1", - "sspMsgContent": "1", + "doNotUse4": "1", + "doNotUse3": "1", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json index 2f4952e9f..51dfd7ae7 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_multi_rsu_no_sdw.json @@ -130,8 +130,8 @@ "direction": "1111111111111111" } ], - "sspMsgTypes": "1", - "sspMsgContent": "1", + "doNotUse4": "1", + "doNotUse3": "1", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json index 069ee9367..79a8b0988 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_path_xy_node_latlon_no_rsu_sdw.json @@ -106,8 +106,8 @@ "direction": "1111111111111111" } ], - "sspMsgTypes": "1", - "sspMsgContent": "1", + "doNotUse4": "1", + "doNotUse3": "1", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json index 745445cac..4ec8c4f74 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_multiRSU.json @@ -107,8 +107,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json index 43c7a926b..650183172 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU.json @@ -91,8 +91,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json index f1045163e..24dc9c2d4 100644 --- a/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json +++ b/data/TIM_Message_Testing_Files/deprecated/tim_region_singleRSU_hexCRC.json @@ -91,8 +91,8 @@ } } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "250" diff --git a/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json index ed074cb2b..529616f8e 100644 --- a/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/tim_path_LL_single_rsu_no_sdw.json @@ -96,8 +96,8 @@ "direction": "0000000000001010" } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json b/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json index 30c02513e..375fb7060 100644 --- a/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json +++ b/data/TIM_Message_Testing_Files/tim_path_multiRSU_hexCRC.json @@ -124,8 +124,8 @@ "direction": "0000000000001010" } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "513" diff --git a/data/TIM_Message_Testing_Files/tim_path_singleRSU.json b/data/TIM_Message_Testing_Files/tim_path_singleRSU.json index 0d22102d5..9b95a62db 100644 --- a/data/TIM_Message_Testing_Files/tim_path_singleRSU.json +++ b/data/TIM_Message_Testing_Files/tim_path_singleRSU.json @@ -108,8 +108,8 @@ "direction": "0000000000001010" } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": [ "513" diff --git a/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json b/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json index e255ea9e2..0eb504b71 100644 --- a/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json +++ b/data/TIM_Message_Testing_Files/tim_path_xy_node_any_single_rsu_no_sdw.json @@ -135,8 +135,8 @@ "direction": "0000000000001010" } ], - "sspMsgTypes": "2", - "sspMsgContent": "3", + "doNotUse4": "2", + "doNotUse3": "3", "content": "Advisory", "items": ["125","some text", "250", "'98765"], "url": "null" diff --git a/docs/ODESwagger.yaml b/docs/ODESwagger.yaml index 399cc96ab..382302c24 100644 --- a/docs/ODESwagger.yaml +++ b/docs/ODESwagger.yaml @@ -391,9 +391,9 @@ definitions: type: array items: $ref: '#/definitions/Region' - sspMsgTypes: + doNotUse4: type: integer - sspMsgContent: + doNotUse3: type: integer content: type: string diff --git a/docs/index.html b/docs/index.html index 01073fab3..8cf5f42f5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1337,10 +1337,10 @@ "$ref" : "#/definitions/Region" } }, - "sspMsgTypes" : { + "doNotUse4" : { "type" : "integer" }, - "sspMsgContent" : { + "doNotUse3" : { "type" : "integer" }, "content" : { diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index c1394155a..126ccb2f2 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -53,7 +53,7 @@ Logger getLogger(String value) { void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -69,7 +69,7 @@ void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtils void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"sspTimRights\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"sspLocationRights\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"sspMsgTypes\":\"1\",\"sspMsgContent\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -85,7 +85,7 @@ void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"sspTimRights\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"sspLocationRights\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"sspMsgTypes\":\"1\",\"sspMsgContent\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -100,7 +100,7 @@ void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { @Test void testGeometryUnavailable() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -116,7 +116,7 @@ void testGeometryUnavailable() throws JsonUtilsException { @Test void testGeometryExitServiceForward() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -132,7 +132,7 @@ void testGeometryExitServiceForward() throws JsonUtilsException { @Test void testGeometryAdvisoryReverse() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -148,7 +148,7 @@ void testGeometryAdvisoryReverse() throws JsonUtilsException { @Test void testRoadSignIDWorkzone() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"sspTimRights\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -163,7 +163,7 @@ void testRoadSignIDWorkzone() throws JsonUtilsException { @Test void testGeometryBothGenericSign() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"sspTimRights\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -179,7 +179,7 @@ void testGeometryBothGenericSign() throws JsonUtilsException { @Test void testPathSpeedLimit() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"sspTimRights\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"sspLocationRights\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"sspMsgTypes\": \"2\", \"sspMsgContent\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -252,7 +252,7 @@ void testBuildItem() { @Test void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -268,7 +268,7 @@ void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { @Test void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -284,7 +284,7 @@ void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsExce @Test void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -300,7 +300,7 @@ void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsExce @Test void testOldRegionWithCircle() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -316,7 +316,7 @@ void testOldRegionWithCircle() throws JsonUtilsException { @Test void testOldRegionWithRegionPointSet() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"sspLocationRights\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"sspMsgTypes\":\"2\",\"sspMsgContent\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 8911c5bcf..c1068c03e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -197,7 +197,7 @@ public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier captur @Test public void testSuccessfulRsuMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"sspTimRights\": \"1\", \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"sspLocationRights\": \"1\", \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"sspMsgTypes\": \"1\", \"sspMsgContent\": \"1\", \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; + String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"doNotUse1\": \"1\", \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"doNotUse2\": \"1\", \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"doNotUse4\": \"1\", \"doNotUse3\": \"1\", \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index e9ac6268e..45b0d43a2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -86,9 +86,9 @@ void testUpdateRsuCreds_UpdatedWhenEmptyString() { @Test void testObfuscateRsuPassword() { String actual = TimTransmogrifier.obfuscateRsuPassword( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":2,\"doNotUse3\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); assertEquals( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"sspTimRights\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"sspLocationRights\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"sspMsgTypes\":2,\"sspMsgContent\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":3,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":2,\"doNotUse3\":3,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", actual); } diff --git a/jpo-ode-svcs/src/test/resources/sdwRequest.json b/jpo-ode-svcs/src/test/resources/sdwRequest.json index 5542d12bf..8f7f8d4dc 100644 --- a/jpo-ode-svcs/src/test/resources/sdwRequest.json +++ b/jpo-ode-svcs/src/test/resources/sdwRequest.json @@ -82,8 +82,8 @@ "direction": "1000000000000001" } ], - "sspMsgTypes": "1", - "sspMsgContent": "1", + "doNotUse4": "1", + "doNotUse3": "1", "content": "advisory", "items": [ "5127" diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json index f10840371..96c7a4d40 100644 --- a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json @@ -31,7 +31,7 @@ { "startDateTime": "2024-09-25T10:00:00.000Z", "durationTime": 8640, - "sspTimRights": "0", + "doNotUse1": "0", "frameType": "advisory", "msgId": { "roadSignID": { @@ -70,8 +70,8 @@ "direction": "1111000011110000" } ], - "sspMsgTypes": "0", - "sspMsgContent": "0", + "doNotUse4": "0", + "doNotUse3": "0", "content": "advisory", "items": [ "4868" From 623acf691ce737716612337c014c076983e3d28e Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 12:26:40 -0700 Subject: [PATCH 078/264] Updated expected output in tests for TravelerMessageFromHumanToAsnConverter class --- ...lerMessageFromHumanToAsnConverterTest.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 126ccb2f2..7fb9a3fa7 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -57,7 +57,7 @@ void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtils TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, @@ -73,7 +73,7 @@ void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, @@ -89,7 +89,7 @@ void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, @@ -104,7 +104,7 @@ void testGeometryUnavailable() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -120,7 +120,7 @@ void testGeometryExitServiceForward() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -136,7 +136,7 @@ void testGeometryAdvisoryReverse() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -152,7 +152,7 @@ void testRoadSignIDWorkzone() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, @@ -167,7 +167,7 @@ void testGeometryBothGenericSign() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -183,7 +183,7 @@ void testPathSpeedLimit() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, @@ -256,7 +256,7 @@ void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -272,7 +272,7 @@ void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsExce TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -288,7 +288,7 @@ void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsExce TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -304,7 +304,7 @@ void testOldRegionWithCircle() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); @@ -320,7 +320,7 @@ void testOldRegionWithRegionPointSet() throws JsonUtilsException { TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); JSONObject timObject = new JSONObject(); From 80a061fe6cbe93510ad9e97cd062ca65550dc850 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 13:13:13 -0700 Subject: [PATCH 079/264] Implemented unit tests for converting pre-2024 TIM requests to comply with J2735 2024 --- ...lerMessageFromHumanToAsnConverterTest.java | 661 ++++++++++-------- .../j2735/builders/timRequest_J2735-2016.json | 146 ++++ ...uest_J2735-2016_ConvertedToJ2735-2024.json | 1 + .../j2735/builders/timRequest_J2735-2020.json | 146 ++++ ...uest_J2735-2020_ConvertedToJ2735-2024.json | 1 + .../builders/timRequest_pre-J2735-2016.json | 146 ++++ ..._pre-J2735-2016_ConvertedToJ2735-2024.json | 1 + 7 files changed, 807 insertions(+), 295 deletions(-) create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 7fb9a3fa7..e4f80ee41 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -1,12 +1,12 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the @@ -16,6 +16,8 @@ package us.dot.its.jpo.ode.plugin.j2735.builders; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import org.json.JSONObject; import org.json.XML; @@ -36,296 +38,365 @@ import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; class TravelerMessageFromHumanToAsnConverterTest { - @Mocked - Logger logger; - - @BeforeEach - void setup() { - new MockUp() { - @Mock - Logger getLogger(String value) { - return logger; - } - }; - } - - @Test - void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryUnavailable() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryExitServiceForward() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryAdvisoryReverse() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testRoadSignIDWorkzone() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryBothGenericSign() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testPathSpeedLimit() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testTranslateISOTimeStampToMinuteOfYear() { - Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); - - Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); - - // Test for invalid timestamp - Assertions.assertEquals(527040, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-15-44T25:66:77.999Z")); - } - - @Test - void testReplaceDataFrameTimestamp() { - String fieldName = "startDateTime"; - ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); - - startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T10:00-06:00"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); - - // Test for invalid timestamp - startDateTime = JsonUtils.newNode().put(fieldName, "2018-15-44T25:66:77.999Z"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(0, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(527040, startDateTime.get("startTime").asLong()); - } - - @Test - void testBuildItem() { - - String itisCode = "123"; - String itis = "itis"; - ObjectNode expectedItisNode = JsonUtils.newNode().put(itis, Integer.parseInt(itisCode)); - ObjectNode expecteditem = (ObjectNode) JsonUtils.newNode().set("item", expectedItisNode); - - // build ITIS code - JsonNode actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(itisCode); - Assertions.assertEquals(expecteditem, actualItem); - - // build number text - expectedItisNode.remove(itis); - expectedItisNode.put("text", itisCode); - actualItem = TravelerMessageFromHumanToAsnConverter.buildItem("'123"); - Assertions.assertEquals(expecteditem, actualItem); - - // build alphanumeric text - String test123 = "test 123"; - expectedItisNode.put("text", test123); - actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(test123); - Assertions.assertEquals(expecteditem, actualItem); - } - - @Test - void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithCircle() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithRegionPointSet() throws JsonUtilsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } + @Mocked + Logger logger; + + @BeforeEach + void setup() { + new MockUp() { + @Mock + Logger getLogger(String value) { + return logger; + } + }; + } + + @Test + void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryUnavailable() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryExitServiceForward() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryAdvisoryReverse() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testRoadSignIDWorkzone() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryBothGenericSign() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testPathSpeedLimit() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testTranslateISOTimeStampToMinuteOfYear() { + Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); + + Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); + + // Test for invalid timestamp + Assertions.assertEquals(527040, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-15-44T25:66:77.999Z")); + } + + @Test + void testReplaceDataFrameTimestamp() { + String fieldName = "startDateTime"; + ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); + + startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T10:00-06:00"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); + + // Test for invalid timestamp + startDateTime = JsonUtils.newNode().put(fieldName, "2018-15-44T25:66:77.999Z"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(0, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(527040, startDateTime.get("startTime").asLong()); + } + + @Test + void testBuildItem() { + + String itisCode = "123"; + String itis = "itis"; + ObjectNode expectedItisNode = JsonUtils.newNode().put(itis, Integer.parseInt(itisCode)); + ObjectNode expecteditem = (ObjectNode) JsonUtils.newNode().set("item", expectedItisNode); + + // build ITIS code + JsonNode actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(itisCode); + Assertions.assertEquals(expecteditem, actualItem); + + // build number text + expectedItisNode.remove(itis); + expectedItisNode.put("text", itisCode); + actualItem = TravelerMessageFromHumanToAsnConverter.buildItem("'123"); + Assertions.assertEquals(expecteditem, actualItem); + + // build alphanumeric text + String test123 = "test 123"; + expectedItisNode.put("text", test123); + actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(test123); + Assertions.assertEquals(expecteditem, actualItem); + } + + @Test + void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithCircle() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithRegionPointSet() throws JsonUtilsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + /** + * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 + * Prior to J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgContent' + * - 'doNotUse4' was 'sspMsgTypes' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtilsException { + // prepare + String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json"))); + ObjectNode inputTID = JsonUtils.toObjectNode(timRequestPreJ2735_2016); + + // execute + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + // verify + String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json"))); + Assertions.assertEquals(expectedTID, inputTID.toString()); + } + + /** + * Test method for converting J2735-2016 ASN.1 to J2735-2024 ASN.1 + * In J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgRights1' + * - 'doNotUse4' was 'sspMsgRights2' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertJ2735_2016ToJ2735_2024() throws IOException, JsonUtilsException { + // prepare + String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json"))); + ObjectNode inputTID = JsonUtils.toObjectNode(timRequestJ2735_2016); + + // execute + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + // verify + String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json"))); + Assertions.assertEquals(expectedTID, inputTID.toString()); + } + + /** + * Test method for converting J2735-2020 ASN.1 to J2735-2024 ASN.1 + * In J2735 2020, the following fields had different names: + * - 'doNotUse1' was 'notUsed' + * - 'doNotUse2' was 'notUsed1' + * - 'doNotUse3' was 'notUsed2' + * - 'doNotUse4' was 'notUsed3' + */ + @Test + void testConvertJ2735_2020ToJ2735_2024() throws IOException, JsonUtilsException { + // prepare + String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json"))); + ObjectNode inputTID = JsonUtils.toObjectNode(timRequestJ2735_2016); + + // execute + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + // verify + String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json"))); + Assertions.assertEquals(expectedTID, inputTID.toString()); + } + } diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json new file mode 100644 index 000000000..ddba9e28e --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json @@ -0,0 +1,146 @@ +{ + "request": { + "rsus": [ + { + "rsuIndex": "10", + "rsuTarget": "127.0.0.2", + "rsuUsername": "v3user", + "rsuPassword": "password", + "rsuRetries": "1", + "rsuTimeout": "1000" + } + ], + "snmp": { + "rsuid": "00000083", + "msgid": "31", + "mode": "1", + "channel": "178", + "interval": "2", + "deliverystart": "2017-06-01T17:47:11-05:00", + "deliverystop": "2018-01-01T17:47:11-05:15", + "enable": "1", + "status": "4" + } + }, + "tim": { + "msgCnt": "1", + "timeStamp": "2017-08-03T22:25:36.297Z", + "urlB": "null", + "packetID": "EC9C236B0000000000", + "dataframes": [ + { + "startDateTime": "2017-08-02T22:25:00.000Z", + "duratonTime": 1, + "sspTimRights": "0", + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { + "latitude": "41.678473", + "longitude": "-108.782775", + "elevation": "917.1432" + }, + "viewAngle": "1010101010101010", + "mutcdCode": "warning", + "crc": "0000" + } + }, + "priority": "0", + "sspLocationRights": "0", + "regions": [ + { + "name": "Testing TIM", + "regulatorID": "0", + "segmentID": "33", + "anchorPosition": { + "latitude": "41.2500807", + "longitude": "-111.0093847", + "elevation": "2020.6969900289998" + }, + "laneWidth": "7", + "directionality": "3", + "closedPath": "false", + "description": "path", + "path": { + "scale": "0", + "type": "ll", + "nodes": [ + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL" + }, + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL1" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL2" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL3" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL4" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL5" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL6" + }, + { + "nodeLong": "-111.0093847", + "nodeLat": "41.2500807", + "delta": "node-LatLon" + } + ] + }, + "direction": "0000000000001010" + } + ], + "sspMsgRights2": "2", + "sspMsgRights1": "3", + "content": "Advisory", + "items": ["125","some text", "250", "'98765"], + "url": "null" + } + ] + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json new file mode 100644 index 000000000..397f5cdb1 --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json @@ -0,0 +1 @@ +{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json new file mode 100644 index 000000000..928d68f3a --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json @@ -0,0 +1,146 @@ +{ + "request": { + "rsus": [ + { + "rsuIndex": "10", + "rsuTarget": "127.0.0.2", + "rsuUsername": "v3user", + "rsuPassword": "password", + "rsuRetries": "1", + "rsuTimeout": "1000" + } + ], + "snmp": { + "rsuid": "00000083", + "msgid": "31", + "mode": "1", + "channel": "178", + "interval": "2", + "deliverystart": "2017-06-01T17:47:11-05:00", + "deliverystop": "2018-01-01T17:47:11-05:15", + "enable": "1", + "status": "4" + } + }, + "tim": { + "msgCnt": "1", + "timeStamp": "2017-08-03T22:25:36.297Z", + "urlB": "null", + "packetID": "EC9C236B0000000000", + "dataframes": [ + { + "startDateTime": "2017-08-02T22:25:00.000Z", + "durationTime": 1, + "notUsed": "0", + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { + "latitude": "41.678473", + "longitude": "-108.782775", + "elevation": "917.1432" + }, + "viewAngle": "1010101010101010", + "mutcdCode": "warning", + "crc": "0000" + } + }, + "priority": "0", + "notUsed1": "0", + "regions": [ + { + "name": "Testing TIM", + "regulatorID": "0", + "segmentID": "33", + "anchorPosition": { + "latitude": "41.2500807", + "longitude": "-111.0093847", + "elevation": "2020.6969900289998" + }, + "laneWidth": "7", + "directionality": "3", + "closedPath": "false", + "description": "path", + "path": { + "scale": "0", + "type": "ll", + "nodes": [ + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL" + }, + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL1" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL2" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL3" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL4" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL5" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL6" + }, + { + "nodeLong": "-111.0093847", + "nodeLat": "41.2500807", + "delta": "node-LatLon" + } + ] + }, + "direction": "0000000000001010" + } + ], + "notUsed3": "2", + "notUsed2": "3", + "content": "Advisory", + "items": ["125","some text", "250", "'98765"], + "url": "null" + } + ] + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json new file mode 100644 index 000000000..abb6abb0c --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json @@ -0,0 +1 @@ +{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"durationTime":1,"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json new file mode 100644 index 000000000..dffa502de --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json @@ -0,0 +1,146 @@ +{ + "request": { + "rsus": [ + { + "rsuIndex": "10", + "rsuTarget": "127.0.0.2", + "rsuUsername": "v3user", + "rsuPassword": "password", + "rsuRetries": "1", + "rsuTimeout": "1000" + } + ], + "snmp": { + "rsuid": "00000083", + "msgid": "31", + "mode": "1", + "channel": "178", + "interval": "2", + "deliverystart": "2017-06-01T17:47:11-05:00", + "deliverystop": "2018-01-01T17:47:11-05:15", + "enable": "1", + "status": "4" + } + }, + "tim": { + "msgCnt": "1", + "timeStamp": "2017-08-03T22:25:36.297Z", + "urlB": "null", + "packetID": "EC9C236B0000000000", + "dataframes": [ + { + "startDateTime": "2017-08-02T22:25:00.000Z", + "duratonTime": 1, + "sspTimRights": "0", + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { + "latitude": "41.678473", + "longitude": "-108.782775", + "elevation": "917.1432" + }, + "viewAngle": "1010101010101010", + "mutcdCode": "warning", + "crc": "0000" + } + }, + "priority": "0", + "sspLocationRights": "0", + "regions": [ + { + "name": "Testing TIM", + "regulatorID": "0", + "segmentID": "33", + "anchorPosition": { + "latitude": "41.2500807", + "longitude": "-111.0093847", + "elevation": "2020.6969900289998" + }, + "laneWidth": "7", + "directionality": "3", + "closedPath": "false", + "description": "path", + "path": { + "scale": "0", + "type": "ll", + "nodes": [ + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL" + }, + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL1" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL2" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL3" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL4" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL5" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL6" + }, + { + "nodeLong": "-111.0093847", + "nodeLat": "41.2500807", + "delta": "node-LatLon" + } + ] + }, + "direction": "0000000000001010" + } + ], + "sspMsgTypes": "2", + "sspMsgContent": "3", + "content": "Advisory", + "items": ["125","some text", "250", "'98765"], + "url": "null" + } + ] + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json new file mode 100644 index 000000000..397f5cdb1 --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json @@ -0,0 +1 @@ +{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file From 641ae071b273262db71a18f1467aa15a894de62a Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 27 Nov 2024 13:24:32 -0700 Subject: [PATCH 080/264] Introduce Checkstyle Linter to GH pipeline and provide steps for local configuration (#120) * add spotless to parent pom.xml and ignore its local artifacts * add google style as default java formatter to settings.json for VSCode * add checkstyle with Google style to the parent pom.xml * add checkstyle-suppressions.xml with suppression of AbbreviationAsWordInName * replace checkstyle-suppressions.xml with modified google style in checkstyle.xml to allow for use of CI tooling * introduce GH Action to annotate checkstyle violations on all changed files in a PR * add trailing whitespace to InetPacketException to confirm GH Action works as expected (only warns about files changed) * use checkstyle.xml as GH action checkstyle config * use checkstyle.xml to reformat InetPacketException now that we can confirm PR is annotated with checkstyle failures for only changed files * move GHA checkstyle job to own checkstyle.yml to only run on pull_request * add space in InetPacketException to trigger checkstyle violation and confirm only one reported violation on PR * reformat InetPacketException to correct checkstyle violations and show no violations reported when pushing style-conforming code * update README.md with Checkstyle documentation and leave comment on modification in checkstyle.xml * add mvn command to README.md * remove unused spotless maven plugin * undo erroneous change to vscode settings.json --- .github/workflows/checkstyle.yml | 16 + .gitignore | 2 + README.md | 15 + checkstyle.xml | 358 ++++++++++++++++++ .../its/jpo/ode/inet/InetPacketException.java | 25 +- pom.xml | 36 ++ 6 files changed, 440 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/checkstyle.yml create mode 100644 checkstyle.xml diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml new file mode 100644 index 000000000..ad337bc7e --- /dev/null +++ b/.github/workflows/checkstyle.yml @@ -0,0 +1,16 @@ +name: checkstyle + +on: pull_request + +jobs: + checkstyle: + name: runner / checkstyle + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: dbelyaev/action-checkstyle@v1.7.0 + with: + github_token: ${{ secrets.github_token }} + reporter: github-pr-review + level: warning + checkstyle_config: 'checkstyle.xml' \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2f3388c2c..bb4e263a1 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,8 @@ settings.xml .metadata *.pyc /kafka/ +**/target/** +**/.rewrite-cache/** #################### ### jpo-ode-svcs ### diff --git a/README.md b/README.md index 2ae921377..8e5cd34c5 100644 --- a/README.md +++ b/README.md @@ -546,6 +546,21 @@ Install the IDE of your choice: The project can be reopened inside a dev container in VSCode. This environment should have all the necessary dependencies to debug the ODE and its submodules. When attempting to run scripts in this environment, it may be necessary to make them executable with "chmod +x" first. + +### Checkstyle configuration + +This project uses [Checkstyle](https://github.com/checkstyle/checkstyle) with a modified version +of Google's Java Style guide to weakly enforce style standards. To configure Checkstyle with your +chosen IDE follow one of the following guides. This repo's checkstyle configuration file can be found +[here](checkstyle.xml). For a quick guide to Checkstyle, check out this short [article](https://www.baeldung.com/checkstyle-java). + +- [Intellij](https://plugins.jetbrains.com/plugin/1065-checkstyle-idea) +- [VSCode](https://code.visualstudio.com/docs/java/java-linting#_checkstyle) +- [Eclipse](https://checkstyle.org/eclipse-cs/#!/project-setup) + +If you prefer the command line for your checkstyle output. You can run `mvn checkstyle:check` to +check the whole project. See [Checkstyle's Github](https://github.com/checkstyle/checkstyle) for more info. + [Back to top](#table-of-contents) diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 000000000..842f596c3 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,358 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketException.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketException.java index 3058b4774..10c681bec 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketException.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketException.java @@ -1,29 +1,30 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.inet; public class InetPacketException extends Exception { - - private static final long serialVersionUID = 1L; - public InetPacketException(String message) { - super(message); - } - - public InetPacketException(String message, Throwable cause) { - super(message, cause); - } + private static final long serialVersionUID = 1L; + + public InetPacketException(String message) { + super(message); + } + + public InetPacketException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/pom.xml b/pom.xml index 51f71250f..a141cedab 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,7 @@ 21 usdot-jpo-ode https://sonarcloud.io + 3.6.0 0.8.11 jacoco @@ -171,9 +172,44 @@ maven-release-plugin 3.0.1 + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + checkstyle-suppressions.xml + UTF-8 + UTF-8 + true + true + false + + + + validate + validate + + check + + + +
+ + + + org.apache.maven.plugins + maven-checkstyle-plugin + ${checkstyle-maven-plugin.version} + + checkstyle.xml + + + + github From 41a93df84ab396c9695ec23191571e6e36de0f00 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 14:26:27 -0700 Subject: [PATCH 081/264] created failing test for OdeTravelerInputDataTest to validate serdes --- .../ode/model/OdeTravelerInputDataTest.java | 43 ++++++ .../ode/model/timRequest_pre-J2735-2016.json | 146 ++++++++++++++++++ ..._pre-J2735-2016_ConvertedToJ2735-2024.json | 1 + 3 files changed, 190 insertions(+) create mode 100644 jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java create mode 100644 jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json create mode 100644 jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java new file mode 100644 index 000000000..f541c910d --- /dev/null +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.model; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import lombok.val; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; +import us.dot.its.jpo.ode.util.JsonUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.*; + +class OdeTravelerInputDataTest { + + /** + * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 + * Prior to J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgContent' + * - 'doNotUse4' was 'sspMsgTypes' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtils.JsonUtilsException { + // prepare + String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + val inputTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); + + // execute +// TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + // verify + String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json"))); + Assertions.assertEquals(expectedTID, inputTID.toString()); + } + +} \ No newline at end of file diff --git a/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json new file mode 100644 index 000000000..dffa502de --- /dev/null +++ b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json @@ -0,0 +1,146 @@ +{ + "request": { + "rsus": [ + { + "rsuIndex": "10", + "rsuTarget": "127.0.0.2", + "rsuUsername": "v3user", + "rsuPassword": "password", + "rsuRetries": "1", + "rsuTimeout": "1000" + } + ], + "snmp": { + "rsuid": "00000083", + "msgid": "31", + "mode": "1", + "channel": "178", + "interval": "2", + "deliverystart": "2017-06-01T17:47:11-05:00", + "deliverystop": "2018-01-01T17:47:11-05:15", + "enable": "1", + "status": "4" + } + }, + "tim": { + "msgCnt": "1", + "timeStamp": "2017-08-03T22:25:36.297Z", + "urlB": "null", + "packetID": "EC9C236B0000000000", + "dataframes": [ + { + "startDateTime": "2017-08-02T22:25:00.000Z", + "duratonTime": 1, + "sspTimRights": "0", + "frameType": "advisory", + "msgId": { + "roadSignID": { + "position": { + "latitude": "41.678473", + "longitude": "-108.782775", + "elevation": "917.1432" + }, + "viewAngle": "1010101010101010", + "mutcdCode": "warning", + "crc": "0000" + } + }, + "priority": "0", + "sspLocationRights": "0", + "regions": [ + { + "name": "Testing TIM", + "regulatorID": "0", + "segmentID": "33", + "anchorPosition": { + "latitude": "41.2500807", + "longitude": "-111.0093847", + "elevation": "2020.6969900289998" + }, + "laneWidth": "7", + "directionality": "3", + "closedPath": "false", + "description": "path", + "path": { + "scale": "0", + "type": "ll", + "nodes": [ + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL" + }, + { + "nodeLong": "0.0002047", + "nodeLat": "-0.0002048", + "delta": "node-LL1" + }, + { + "nodeLong": "0.0008191", + "nodeLat": "-0.0008192", + "delta": "node-LL2" + }, + { + "nodeLong": "0.0032767", + "nodeLat": "-0.0032768", + "delta": "node-LL3" + }, + { + "nodeLong": "0.0131071", + "nodeLat": "-0.0131072", + "delta": "node-LL4" + }, + { + "nodeLong": "0.2097151", + "nodeLat": "-0.2097152", + "delta": "node-LL5" + }, + { + "nodeLong": "0.8388607", + "nodeLat": "-0.8388608", + "delta": "node-LL6" + }, + { + "nodeLong": "-111.0093847", + "nodeLat": "41.2500807", + "delta": "node-LatLon" + } + ] + }, + "direction": "0000000000001010" + } + ], + "sspMsgTypes": "2", + "sspMsgContent": "3", + "content": "Advisory", + "items": ["125","some text", "250", "'98765"], + "url": "null" + } + ] + } +} \ No newline at end of file diff --git a/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json new file mode 100644 index 000000000..397f5cdb1 --- /dev/null +++ b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json @@ -0,0 +1 @@ +{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file From 046c7b1591f96de93385cc888e782e2c0e1d38c5 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 14:36:53 -0700 Subject: [PATCH 082/264] added JsonAlias annotations to OdeTravelerInformationMessage.java to support deserialization of pre-J2735-2016 TIM messages --- .../us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java | 3 +-- .../jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java index f541c910d..a45a986aa 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -30,10 +30,9 @@ void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtils.JsonUt // prepare String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); ObjectMapper mapper = new ObjectMapper(); - val inputTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); // execute -// TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + val inputTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); // verify String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json"))); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index 042037fbc..5d5871ee0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -17,6 +17,7 @@ import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.databind.JsonNode; import us.dot.its.jpo.ode.model.OdeObject; @@ -450,15 +451,20 @@ public void setdElevation(BigDecimal dElevation) { public static class DataFrame extends OdeObject { private static final long serialVersionUID = 537503046055742396L; + @JsonAlias("sspTimRights") private short doNotUse1;// Start Header Information private FrameType.TravelerInfoType frameType; private MsgId msgId; private String startDateTime; + @JsonAlias("duratonTime") private int durationTime; private int priority;// End header Information + @JsonAlias("sspLocationRights") private short doNotUse2;// Start Region Information private Region[] regions; + @JsonAlias("sspMsgContent") private short doNotUse3;// Start content Information + @JsonAlias("sspMsgTypes") private short doNotUse4; private String content; private String[] items; From 3a9c2987340f9d796e4ce7c726b41bfb08267c37 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Wed, 27 Nov 2024 15:57:00 -0700 Subject: [PATCH 083/264] generated hashCode and equals methods for all subclasses needed to test equivalence of OdeTravelerInputData objects --- .../jpo/ode/model/OdeTravelerInputData.java | 61 ++- .../ode/model/OdeTravelerInputDataTest.java | 153 ++++++- .../its/jpo/ode/plugin/ServiceRequest.java | 2 + .../j2735/OdeTravelerInformationMessage.java | 381 +++++++++++++++++- 4 files changed, 579 insertions(+), 18 deletions(-) diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java index 391f840a1..35cbd2280 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java @@ -15,18 +15,20 @@ ******************************************************************************/ package us.dot.its.jpo.ode.model; +import lombok.Data; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; +@Data public class OdeTravelerInputData extends OdeObject { - private static final long serialVersionUID = 8769107278440796699L; + private static final long serialVersionUID = 8769107278440796699L; - private ServiceRequest request; - - private OdeTravelerInformationMessage tim; - - public ServiceRequest getRequest() { + private ServiceRequest request; + + private OdeTravelerInformationMessage tim; + + public ServiceRequest getRequest() { return request; } @@ -35,11 +37,48 @@ public void setRequest(ServiceRequest request) { } public OdeTravelerInformationMessage getTim() { - return tim; - } + return tim; + } - public void setTim(OdeTravelerInformationMessage tim) { - this.tim = tim; - } + public void setTim(OdeTravelerInformationMessage tim) { + this.tim = tim; + } + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof OdeTravelerInputData)) { + return false; + } + final OdeTravelerInputData other = (OdeTravelerInputData) o; + if (!other.canEqual((Object) this)) { + return false; + } + final Object this$request = this.getRequest(); + final Object other$request = other.getRequest(); + if (this$request == null ? other$request != null : !this$request.equals(other$request)) { + return false; + } + final Object this$tim = this.getTim(); + final Object other$tim = other.getTim(); + if (this$tim == null ? other$tim != null : !this$tim.equals(other$tim)) { + return false; + } + return true; + } + + protected boolean canEqual(final Object other) { + return other instanceof OdeTravelerInputData; + } + + public int hashCode() { + final int PRIME = 59; + int result = 1; + final Object $request = this.getRequest(); + result = result * PRIME + ($request == null ? 43 : $request.hashCode()); + final Object $tim = this.getTim(); + result = result * PRIME + ($tim == null ? 43 : $tim.hashCode()); + return result; + } } diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java index a45a986aa..738eb7ce6 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -2,10 +2,20 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.math.BigDecimal; +import java.util.Arrays; import lombok.val; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.plugin.RoadSideUnit; +import us.dot.its.jpo.ode.plugin.SNMP; +import us.dot.its.jpo.ode.plugin.ServiceRequest; +import us.dot.its.jpo.ode.plugin.SnmpProtocol; +import us.dot.its.jpo.ode.plugin.j2735.OdePosition3D; +import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; +import us.dot.its.jpo.ode.plugin.j2735.timstorage.MutcdCode; import us.dot.its.jpo.ode.util.JsonUtils; import java.io.IOException; @@ -16,6 +26,10 @@ class OdeTravelerInputDataTest { + // create an OdeTravelerInputData object using: + // {"request":{"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10,"snmpProtocol":"NTCIP1218"}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"tim":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse3":3,"doNotUse4":2,"content":"Advisory","items":["125","some text","250","'98765"],"url":"null"}]}} + OdeTravelerInputData exp = new OdeTravelerInputData(); + /** * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 * Prior to J2735 2016, the following fields had different names: @@ -31,12 +45,143 @@ void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtils.JsonUt String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); ObjectMapper mapper = new ObjectMapper(); + // create an OdeTravelerInputData object using: + // {"request":{"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10,"snmpProtocol":"NTCIP1218"}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"tim":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse3":3,"doNotUse4":2,"content":"Advisory","items":["125","some text","250","'98765"],"url":"null"}]}} + OdeTravelerInputData expected = new OdeTravelerInputData(); + var req = new ServiceRequest(); + var rsu = new RoadSideUnit.RSU(); + rsu.setRsuTarget("127.0.0.2"); + rsu.setRsuUsername("v3user"); + rsu.setRsuPassword("password"); + rsu.setRsuRetries(1); + rsu.setRsuTimeout(1000); + rsu.setRsuIndex(10); + rsu.setSnmpProtocol(SnmpProtocol.valueOf("NTCIP1218")); + req.setRsus(new RoadSideUnit.RSU[]{rsu}); + var snmp = new SNMP(); + snmp.setRsuid("00000083"); + snmp.setMsgid(31); + snmp.setMode(1); + snmp.setChannel(178); + snmp.setInterval(2); + snmp.setDeliverystart("2017-06-01T17:47:11-05:00"); + snmp.setDeliverystop("2018-01-01T17:47:11-05:15"); + snmp.setEnable(1); + snmp.setStatus(4); + req.setSnmp(snmp); + expected.setRequest(req); + var tim = new OdeTravelerInformationMessage(); + tim.setMsgCnt(1); + tim.setTimeStamp("2017-08-03T22:25:36.297Z"); + tim.setPacketID("EC9C236B0000000000"); + tim.setUrlB("null"); + var dataframes = new OdeTravelerInformationMessage.DataFrame[1]; + var df = new OdeTravelerInformationMessage.DataFrame(); + df.setDoNotUse1((short)0); + df.setFrameType(FrameType.TravelerInfoType.valueOf("advisory")); + var msgId = new OdeTravelerInformationMessage.DataFrame.MsgId(); + var roadSignID = new OdeTravelerInformationMessage.DataFrame.RoadSignID(); + var position = new OdePosition3D(); + position.setLatitude(new BigDecimal("41.678473")); + position.setLongitude(new BigDecimal("-108.782775")); + position.setElevation(new BigDecimal("917.1432")); + roadSignID.setPosition(position); + roadSignID.setViewAngle("1010101010101010"); + roadSignID.setMutcdCode(MutcdCode.MutcdCodeEnum.valueOf("warning")); + roadSignID.setCrc("0000"); + msgId.setRoadSignID(roadSignID); + df.setMsgId(msgId); + df.setStartDateTime("2017-08-02T22:25:00.000Z"); + df.setDurationTime(1); + df.setPriority(0); + df.setDoNotUse2((short)0); + var region = new OdeTravelerInformationMessage.DataFrame.Region(); + region.setName("Testing TIM"); + region.setRegulatorID(0); + region.setSegmentID(33); + var anchorPosition = new OdePosition3D(); + anchorPosition.setLatitude(new BigDecimal("41.2500807")); + anchorPosition.setLongitude(new BigDecimal("-111.0093847")); + anchorPosition.setElevation(new BigDecimal("2020.6969900289998")); + region.setAnchorPosition(anchorPosition); + region.setLaneWidth(BigDecimal.valueOf(7)); + region.setDirectionality("3"); + region.setClosedPath(false); + region.setDirection("0000000000001010"); + region.setDescription("path"); + var path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); + path.setScale(0); + path.setType("ll"); + var nodes = new OdeTravelerInformationMessage.NodeXY[13]; + nodes[0] = new OdeTravelerInformationMessage.NodeXY(); + nodes[0].setDelta("node-LL"); + nodes[0].setNodeLat(BigDecimal.valueOf(-0.0002048)); + nodes[0].setNodeLong(BigDecimal.valueOf(0.0002047)); + nodes[1] = new OdeTravelerInformationMessage.NodeXY(); + nodes[1].setDelta("node-LL"); + nodes[1].setNodeLat(BigDecimal.valueOf(-0.0008192)); + nodes[1].setNodeLong(BigDecimal.valueOf(0.0008191)); + nodes[2] = new OdeTravelerInformationMessage.NodeXY(); + nodes[2].setDelta("node-LL"); + nodes[2].setNodeLat(BigDecimal.valueOf(-0.0032768)); + nodes[2].setNodeLong(BigDecimal.valueOf(0.0032767)); + nodes[3] = new OdeTravelerInformationMessage.NodeXY(); + nodes[3].setDelta("node-LL"); + nodes[3].setNodeLat(BigDecimal.valueOf(-0.0131072)); + nodes[3].setNodeLong(BigDecimal.valueOf(0.0131071)); + nodes[4] = new OdeTravelerInformationMessage.NodeXY(); + nodes[4].setDelta("node-LL"); + nodes[4].setNodeLat(BigDecimal.valueOf(-0.2097152)); + nodes[4].setNodeLong(BigDecimal.valueOf(0.2097151)); + nodes[5] = new OdeTravelerInformationMessage.NodeXY(); + nodes[5].setDelta("node-LL"); + nodes[5].setNodeLat(BigDecimal.valueOf(-0.8388608)); + nodes[5].setNodeLong(BigDecimal.valueOf(0.8388607)); + nodes[6] = new OdeTravelerInformationMessage.NodeXY(); + nodes[6].setDelta("node-LL1"); + nodes[6].setNodeLat(BigDecimal.valueOf(-0.0002048)); + nodes[6].setNodeLong(BigDecimal.valueOf(0.0002047)); + nodes[7] = new OdeTravelerInformationMessage.NodeXY(); + nodes[7].setDelta("node-LL2"); + nodes[7].setNodeLat(BigDecimal.valueOf(-0.0008192)); + nodes[7].setNodeLong(BigDecimal.valueOf(0.0008191)); + nodes[8] = new OdeTravelerInformationMessage.NodeXY(); + nodes[8].setDelta("node-LL3"); + nodes[8].setNodeLat(BigDecimal.valueOf(-0.0032768)); + nodes[8].setNodeLong(BigDecimal.valueOf(0.0032767)); + nodes[9] = new OdeTravelerInformationMessage.NodeXY(); + nodes[9].setDelta("node-LL4"); + nodes[9].setNodeLat(BigDecimal.valueOf(-0.0131072)); + nodes[9].setNodeLong(BigDecimal.valueOf(0.0131071)); + nodes[10] = new OdeTravelerInformationMessage.NodeXY(); + nodes[10].setDelta("node-LL5"); + nodes[10].setNodeLat(BigDecimal.valueOf(-0.2097152)); + nodes[10].setNodeLong(BigDecimal.valueOf(0.2097151)); + nodes[11] = new OdeTravelerInformationMessage.NodeXY(); + nodes[11].setDelta("node-LL6"); + nodes[11].setNodeLat(BigDecimal.valueOf(-0.8388608)); + nodes[11].setNodeLong(BigDecimal.valueOf(0.8388607)); + nodes[12] = new OdeTravelerInformationMessage.NodeXY(); + nodes[12].setDelta("node-LatLon"); + nodes[12].setNodeLat(BigDecimal.valueOf(41.2500807)); + nodes[12].setNodeLong(BigDecimal.valueOf(-111.0093847)); + path.setNodes(nodes); + region.setPath(path); + df.setRegions(new OdeTravelerInformationMessage.DataFrame.Region[]{region}); + df.setDoNotUse3((short)3); + df.setDoNotUse4((short)2); + df.setContent("Advisory"); + df.setItems(new String[]{"125", "some text", "250", "'98765"}); + df.setUrl("null"); + dataframes[0] = df; + tim.setDataframes(dataframes); + expected.setTim(tim); + // execute - val inputTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); + val deserializedTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); - // verify - String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json"))); - Assertions.assertEquals(expectedTID, inputTID.toString()); + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expected, deserializedTID); } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java index e5a8d21cc..14c331a86 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/ServiceRequest.java @@ -17,6 +17,8 @@ import java.util.Arrays; +import lombok.Data; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.model.OdeObject; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index 5d5871ee0..b4d712f30 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -15,11 +15,11 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735; -import java.math.BigDecimal; - import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.databind.JsonNode; - +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Objects; import us.dot.its.jpo.ode.model.OdeObject; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage.DataFrame.Region.Circle; @@ -90,6 +90,60 @@ public void setAsnDataFrames(JsonNode stringDataFrames) { this.asnDataFrames = stringDataFrames; } + public boolean equals(final Object o) { + if (o == this) { + return true; + } + if (!(o instanceof OdeTravelerInformationMessage)) { + return false; + } + final OdeTravelerInformationMessage other = (OdeTravelerInformationMessage) o; + if (!other.canEqual((Object) this)) { + return false; + } + if (this.getMsgCnt() != other.getMsgCnt()) { + return false; + } + final Object this$timeStamp = this.getTimeStamp(); + final Object other$timeStamp = other.getTimeStamp(); + if (this$timeStamp == null ? other$timeStamp != null : + !this$timeStamp.equals(other$timeStamp)) { + return false; + } + final Object this$packetID = this.getPacketID(); + final Object other$packetID = other.getPacketID(); + if (this$packetID == null ? other$packetID != null : !this$packetID.equals(other$packetID)) { + return false; + } + final Object this$urlB = this.getUrlB(); + final Object other$urlB = other.getUrlB(); + if (this$urlB == null ? other$urlB != null : !this$urlB.equals(other$urlB)) { + return false; + } + if (!java.util.Arrays.deepEquals(this.getDataframes(), other.getDataframes())) { + return false; + } + return true; + } + + protected boolean canEqual(final Object other) { + return other instanceof OdeTravelerInformationMessage; + } + + public int hashCode() { + final int PRIME = 59; + int result = 1; + result = result * PRIME + this.getMsgCnt(); + final Object $timeStamp = this.getTimeStamp(); + result = result * PRIME + ($timeStamp == null ? 43 : $timeStamp.hashCode()); + final Object $packetID = this.getPacketID(); + result = result * PRIME + ($packetID == null ? 43 : $packetID.hashCode()); + final Object $urlB = this.getUrlB(); + result = result * PRIME + ($urlB == null ? 43 : $urlB.hashCode()); + result = result * PRIME + java.util.Arrays.deepHashCode(this.getDataframes()); + return result; + } + public static class NodeListXY extends OdeObject { private static final long serialVersionUID = 1L; private ComputedLane computedLane; @@ -143,6 +197,21 @@ public void setRegionPoint(RegionPointSet regionPoint) { this.regionPoint = regionPoint; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Area area = (Area) o; + return Objects.equals(shapepoint, area.shapepoint) && + Objects.equals(circle, area.circle) && + Objects.equals(regionPoint, area.regionPoint); + } + + @Override + public int hashCode() { + return Objects.hash(shapepoint, circle, regionPoint); + } } public static class ComputedLane extends OdeObject { @@ -203,6 +272,25 @@ public void setScaleYaxis(BigDecimal scaleYaxis) { this.scaleYaxis = scaleYaxis; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + ComputedLane that = (ComputedLane) o; + return referenceLaneId == that.referenceLaneId && + Objects.equals(offsetXaxis, that.offsetXaxis) && + Objects.equals(offsetYaxis, that.offsetYaxis) && + Objects.equals(rotateXY, that.rotateXY) && + Objects.equals(scaleXaxis, that.scaleXaxis) && + Objects.equals(scaleYaxis, that.scaleYaxis); + } + + @Override + public int hashCode() { + return Objects.hash(referenceLaneId, offsetXaxis, offsetYaxis, rotateXY, scaleXaxis, + scaleYaxis); + } } public static class NodeXY extends OdeObject { @@ -263,6 +351,23 @@ public void setAttributes(Attributes attributes) { this.attributes = attributes; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + NodeXY nodeXY = (NodeXY) o; + return Objects.equals(delta, nodeXY.delta) && + Objects.equals(nodeLat, nodeXY.nodeLat) && + Objects.equals(nodeLong, nodeXY.nodeLong) && + Objects.equals(x, nodeXY.x) && Objects.equals(y, nodeXY.y) && + Objects.equals(attributes, nodeXY.attributes); + } + + @Override + public int hashCode() { + return Objects.hash(delta, nodeLat, nodeLong, x, y, attributes); + } } public static class LocalNode extends OdeObject { @@ -277,6 +382,20 @@ public long getType() { public void setType(long type) { this.type = type; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + LocalNode localNode = (LocalNode) o; + return type == localNode.type; + } + + @Override + public int hashCode() { + return Objects.hashCode(type); + } } public static class DisabledList extends OdeObject { @@ -291,6 +410,20 @@ public long getType() { public void setType(long type) { this.type = type; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + DisabledList that = (DisabledList) o; + return type == that.type; + } + + @Override + public int hashCode() { + return Objects.hashCode(type); + } } public static class EnabledList extends OdeObject { @@ -305,6 +438,20 @@ public long getType() { public void setType(long type) { this.type = type; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + EnabledList that = (EnabledList) o; + return type == that.type; + } + + @Override + public int hashCode() { + return Objects.hashCode(type); + } } public static class SpeedLimits extends OdeObject { @@ -328,6 +475,20 @@ public BigDecimal getVelocity() { public void setVelocity(BigDecimal velocity) { this.velocity = velocity; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + SpeedLimits that = (SpeedLimits) o; + return type == that.type && Objects.equals(velocity, that.velocity); + } + + @Override + public int hashCode() { + return Objects.hash(type, velocity); + } } public static class DataList extends OdeObject { @@ -387,6 +548,27 @@ public SpeedLimits[] getSpeedLimits() { public void setSpeedLimits(SpeedLimits[] speedLimits) { this.speedLimits = speedLimits; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + DataList dataList = (DataList) o; + return pathEndpointAngle == dataList.pathEndpointAngle && + Objects.equals(laneCrownCenter, dataList.laneCrownCenter) && + Objects.equals(laneCrownLeft, dataList.laneCrownLeft) && + Objects.equals(laneCrownRight, dataList.laneCrownRight) && + Objects.equals(laneAngle, dataList.laneAngle) && + Objects.deepEquals(speedLimits, dataList.speedLimits); + } + + @Override + public int hashCode() { + return Objects.hash(pathEndpointAngle, laneCrownCenter, laneCrownLeft, laneCrownRight, + laneAngle, + Arrays.hashCode(speedLimits)); + } } public static class Attributes extends OdeObject { @@ -446,6 +628,26 @@ public BigDecimal getdElevation() { public void setdElevation(BigDecimal dElevation) { this.dElevation = dElevation; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Attributes that = (Attributes) o; + return Objects.deepEquals(localNodes, that.localNodes) && + Objects.deepEquals(disabledLists, that.disabledLists) && + Objects.deepEquals(enabledLists, that.enabledLists) && + Objects.deepEquals(dataLists, that.dataLists) && + Objects.equals(dWidth, that.dWidth) && + Objects.equals(dElevation, that.dElevation); + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(localNodes), Arrays.hashCode(disabledLists), + Arrays.hashCode(enabledLists), Arrays.hashCode(dataLists), dWidth, dElevation); + } } public static class DataFrame extends OdeObject { @@ -470,6 +672,30 @@ public static class DataFrame extends OdeObject { private String[] items; private String url;// End content Information + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + DataFrame dataFrame = (DataFrame) o; + return doNotUse1 == dataFrame.doNotUse1 && durationTime == dataFrame.durationTime && + priority == dataFrame.priority && doNotUse2 == dataFrame.doNotUse2 && + doNotUse3 == dataFrame.doNotUse3 && doNotUse4 == dataFrame.doNotUse4 && + frameType == dataFrame.frameType && Objects.equals(msgId, dataFrame.msgId) && + Objects.equals(startDateTime, dataFrame.startDateTime) && + Objects.deepEquals(regions, dataFrame.regions) && + Objects.equals(content, dataFrame.content) && + Objects.deepEquals(items, dataFrame.items) && + Objects.equals(url, dataFrame.url); + } + + @Override + public int hashCode() { + return Objects.hash(doNotUse1, frameType, msgId, startDateTime, durationTime, priority, + doNotUse2, + Arrays.hashCode(regions), doNotUse3, doNotUse4, content, Arrays.hashCode(items), url); + } + public static class Region extends OdeObject { private static final long serialVersionUID = 8011973280114768008L; @@ -486,6 +712,31 @@ public static class Region extends OdeObject { private Geometry geometry; private OldRegion oldRegion; + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Region region = (Region) o; + return regulatorID == region.regulatorID && segmentID == region.segmentID && + closedPath == region.closedPath && Objects.equals(name, region.name) && + Objects.equals(anchorPosition, region.anchorPosition) && + Objects.equals(laneWidth, region.laneWidth) && + Objects.equals(directionality, region.directionality) && + Objects.equals(direction, region.direction) && + Objects.equals(description, region.description) && + Objects.equals(path, region.path) && + Objects.equals(geometry, region.geometry) && + Objects.equals(oldRegion, region.oldRegion); + } + + @Override + public int hashCode() { + return Objects.hash(name, regulatorID, segmentID, anchorPosition, laneWidth, + directionality, + closedPath, direction, description, path, geometry, oldRegion); + } + public static class OldRegion extends OdeObject { private static final long serialVersionUID = 1L; @@ -493,6 +744,22 @@ public static class OldRegion extends OdeObject { private String extent; private Area area; + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + OldRegion oldRegion = (OldRegion) o; + return Objects.equals(direction, oldRegion.direction) && + Objects.equals(extent, oldRegion.extent) && + Objects.equals(area, oldRegion.area); + } + + @Override + public int hashCode() { + return Objects.hash(direction, extent, area); + } + public static class ShapePointSet extends OdeObject { private static final long serialVersionUID = 1L; @@ -537,6 +804,22 @@ public void setNodeList(NodeListXY nodeList) { this.nodeList = nodeList; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + ShapePointSet that = (ShapePointSet) o; + return directionality == that.directionality && + Objects.equals(anchor, that.anchor) && + Objects.equals(laneWidth, that.laneWidth) && + Objects.equals(nodeList, that.nodeList); + } + + @Override + public int hashCode() { + return Objects.hash(anchor, laneWidth, directionality, nodeList); + } } public static class RegionPointSet extends OdeObject { @@ -546,6 +829,21 @@ public static class RegionPointSet extends OdeObject { private int scale; private RegionList[] regionList; + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + RegionPointSet that = (RegionPointSet) o; + return scale == that.scale && Objects.equals(position, that.position) && + Objects.deepEquals(regionList, that.regionList); + } + + @Override + public int hashCode() { + return Objects.hash(position, scale, Arrays.hashCode(regionList)); + } + public static class RegionList extends OdeObject { private static final long serialVersionUID = -5307620155601900634L; @@ -576,6 +874,22 @@ public BigDecimal getxOffset() { public void setxOffset(BigDecimal xOffset) { this.xOffset = xOffset; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + RegionList that = (RegionList) o; + return Objects.equals(xOffset, that.xOffset) && + Objects.equals(yOffset, that.yOffset) && + Objects.equals(zOffset, that.zOffset); + } + + @Override + public int hashCode() { + return Objects.hash(xOffset, yOffset, zOffset); + } } public RegionList[] getRegionList() { @@ -716,6 +1030,22 @@ public OdePosition3D getCenter() { public void setCenter(OdePosition3D center) { this.center = center; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Circle circle = (Circle) o; + return radius == circle.radius && Objects.equals(position, circle.position) && + Objects.equals(center, circle.center) && + Objects.equals(units, circle.units); + } + + @Override + public int hashCode() { + return Objects.hash(position, center, radius, units); + } } public static class Path extends OdeObject { @@ -758,6 +1088,21 @@ public void setScale(int scale) { this.scale = scale; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + Path path = (Path) o; + return scale == path.scale && Objects.equals(type, path.type) && + Objects.deepEquals(nodes, path.nodes) && + Objects.equals(computedLane, path.computedLane); + } + + @Override + public int hashCode() { + return Objects.hash(scale, type, Arrays.hashCode(nodes), computedLane); + } } public OldRegion getOldRegion() { @@ -899,6 +1244,21 @@ public void setCrc(String crc) { this.crc = crc; } + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + RoadSignID that = (RoadSignID) o; + return Objects.equals(position, that.position) && + Objects.equals(viewAngle, that.viewAngle) && mutcdCode == that.mutcdCode && + Objects.equals(crc, that.crc); + } + + @Override + public int hashCode() { + return Objects.hash(position, viewAngle, mutcdCode, crc); + } } public static class MsgId extends Asn1Object { @@ -922,6 +1282,21 @@ public String getFurtherInfoID() { public void setFurtherInfoID(String furtherInfoID) { this.furtherInfoID = furtherInfoID; } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + MsgId msgId = (MsgId) o; + return Objects.equals(roadSignID, msgId.roadSignID) && + Objects.equals(furtherInfoID, msgId.furtherInfoID); + } + + @Override + public int hashCode() { + return Objects.hash(roadSignID, furtherInfoID); + } } public MsgId getMsgId() { From 420acc138a43ea7340cf707ea99089692221258c Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 10:57:47 -0700 Subject: [PATCH 084/264] Finished moving conversion tests to jpo-ode-core and adding json aliases to OdeTravelerInformationMessage to support previous J2735 revisions --- .../ode/model/OdeTravelerInputDataTest.java | 67 ++++++-- .../jpo/ode/model}/timRequest_J2735-2016.json | 0 .../jpo/ode/model}/timRequest_J2735-2020.json | 0 ..._pre-J2735-2016_ConvertedToJ2735-2024.json | 1 - .../j2735/OdeTravelerInformationMessage.java | 8 +- ...lerMessageFromHumanToAsnConverterTest.java | 70 +-------- ...uest_J2735-2016_ConvertedToJ2735-2024.json | 1 - ...uest_J2735-2020_ConvertedToJ2735-2024.json | 1 - .../builders/timRequest_pre-J2735-2016.json | 146 ------------------ ..._pre-J2735-2016_ConvertedToJ2735-2024.json | 1 - 10 files changed, 62 insertions(+), 233 deletions(-) rename {jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders => jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model}/timRequest_J2735-2016.json (100%) rename {jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders => jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model}/timRequest_J2735-2020.json (100%) delete mode 100644 jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json delete mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json delete mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json delete mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json delete mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java index 738eb7ce6..5a1175eab 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -26,10 +26,6 @@ class OdeTravelerInputDataTest { - // create an OdeTravelerInputData object using: - // {"request":{"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10,"snmpProtocol":"NTCIP1218"}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"tim":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse3":3,"doNotUse4":2,"content":"Advisory","items":["125","some text","250","'98765"],"url":"null"}]}} - OdeTravelerInputData exp = new OdeTravelerInputData(); - /** * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 * Prior to J2735 2016, the following fields had different names: @@ -40,11 +36,65 @@ class OdeTravelerInputDataTest { * - 'durationTime' was 'duratonTime' */ @Test - void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtils.JsonUtilsException { + void testConvertPreJ2735_2016ToJ2735_2024() throws IOException { // prepare String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + + // execute + val deserializedTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); + + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } + /** + * Test method for converting J2735-2016 ASN.1 to J2735-2024 ASN.1 + * In J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgRights1' + * - 'doNotUse4' was 'sspMsgRights2' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertJ2735_2016ToJ2735_2024() throws IOException { + // prepare + String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + + // execute + val deserializedTID = mapper.readValue(timRequestJ2735_2016, OdeTravelerInputData.class); + + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } + + /** + * Test method for converting J2735-2020 ASN.1 to J2735-2024 ASN.1 + * In J2735 2020, the following fields had different names: + * - 'doNotUse1' was 'notUsed' + * - 'doNotUse2' was 'notUsed1' + * - 'doNotUse3' was 'notUsed2' + * - 'doNotUse4' was 'notUsed3' + */ + @Test + void testConvertJ2735_2020ToJ2735_2024() throws IOException { + // prepare + String timRequestJ2735_2020 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2020.json"))); + ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + + // execute + val deserializedTID = mapper.readValue(timRequestJ2735_2020, OdeTravelerInputData.class); + + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } + + private static OdeTravelerInputData getExpectedDeserializedObject() { // create an OdeTravelerInputData object using: // {"request":{"rsus":[{"rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":1,"rsuTimeout":1000,"rsuIndex":10,"snmpProtocol":"NTCIP1218"}],"snmp":{"rsuid":"00000083","msgid":31,"mode":1,"channel":178,"interval":2,"deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":1,"status":4}},"tim":{"msgCnt":1,"timeStamp":"2017-08-03T22:25:36.297Z","packetID":"EC9C236B0000000000","urlB":"null","dataframes":[{"doNotUse1":0,"frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":41.678473,"longitude":-108.782775,"elevation":917.1432},"viewAngle":"1010101010101010","mutcdCode":"warning","crc":"0000"}},"startDateTime":"2017-08-02T22:25:00.000Z","durationTime":1,"priority":0,"doNotUse2":0,"regions":[{"name":"Testing TIM","regulatorID":0,"segmentID":33,"anchorPosition":{"latitude":41.2500807,"longitude":-111.0093847,"elevation":2020.6969900289998},"laneWidth":7,"directionality":"3","closedPath":false,"direction":"0000000000001010","description":"path","path":{"scale":0,"type":"ll","nodes":[{"delta":"node-LL","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LL1","nodeLat":-0.0002048,"nodeLong":0.0002047},{"delta":"node-LL2","nodeLat":-0.0008192,"nodeLong":0.0008191},{"delta":"node-LL3","nodeLat":-0.0032768,"nodeLong":0.0032767},{"delta":"node-LL4","nodeLat":-0.0131072,"nodeLong":0.0131071},{"delta":"node-LL5","nodeLat":-0.2097152,"nodeLong":0.2097151},{"delta":"node-LL6","nodeLat":-0.8388608,"nodeLong":0.8388607},{"delta":"node-LatLon","nodeLat":41.2500807,"nodeLong":-111.0093847}]}}],"doNotUse3":3,"doNotUse4":2,"content":"Advisory","items":["125","some text","250","'98765"],"url":"null"}]}} OdeTravelerInputData expected = new OdeTravelerInputData(); @@ -176,12 +226,7 @@ void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtils.JsonUt dataframes[0] = df; tim.setDataframes(dataframes); expected.setTim(tim); - - // execute - val deserializedTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); - - // verify (compare inputTID to an expected OdeTravelerInputData object) - Assertions.assertEquals(expected, deserializedTID); + return expected; } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2016.json similarity index 100% rename from jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json rename to jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2016.json diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2020.json similarity index 100% rename from jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json rename to jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2020.json diff --git a/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json deleted file mode 100644 index 397f5cdb1..000000000 --- a/jpo-ode-core/src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json +++ /dev/null @@ -1 +0,0 @@ -{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index b4d712f30..186b6ea76 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -653,7 +653,7 @@ public int hashCode() { public static class DataFrame extends OdeObject { private static final long serialVersionUID = 537503046055742396L; - @JsonAlias("sspTimRights") + @JsonAlias({"sspTimRights", "notUsed"}) private short doNotUse1;// Start Header Information private FrameType.TravelerInfoType frameType; private MsgId msgId; @@ -661,12 +661,12 @@ public static class DataFrame extends OdeObject { @JsonAlias("duratonTime") private int durationTime; private int priority;// End header Information - @JsonAlias("sspLocationRights") + @JsonAlias({"sspLocationRights", "notUsed1"}) private short doNotUse2;// Start Region Information private Region[] regions; - @JsonAlias("sspMsgContent") + @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) private short doNotUse3;// Start content Information - @JsonAlias("sspMsgTypes") + @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) private short doNotUse4; private String content; private String[] items; diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index e4f80ee41..d93cffaf1 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -19,6 +19,8 @@ import java.nio.file.Files; import java.nio.file.Paths; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.val; import org.json.JSONObject; import org.json.XML; import org.junit.jupiter.api.Assertions; @@ -331,72 +333,4 @@ void testOldRegionWithRegionPointSet() throws JsonUtilsException { Assertions.assertNotNull(XML.toString(timObject)); } - /** - * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 - * Prior to J2735 2016, the following fields had different names: - * - 'doNotUse1' was 'sspTimRights' - * - 'doNotUse2' was 'sspLocationRights' - * - 'doNotUse3' was 'sspMsgContent' - * - 'doNotUse4' was 'sspMsgTypes' - * - 'durationTime' was 'duratonTime' - */ - @Test - void testConvertPreJ2735_2016ToJ2735_2024() throws IOException, JsonUtilsException { - // prepare - String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json"))); - ObjectNode inputTID = JsonUtils.toObjectNode(timRequestPreJ2735_2016); - - // execute - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - // verify - String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json"))); - Assertions.assertEquals(expectedTID, inputTID.toString()); - } - - /** - * Test method for converting J2735-2016 ASN.1 to J2735-2024 ASN.1 - * In J2735 2016, the following fields had different names: - * - 'doNotUse1' was 'sspTimRights' - * - 'doNotUse2' was 'sspLocationRights' - * - 'doNotUse3' was 'sspMsgRights1' - * - 'doNotUse4' was 'sspMsgRights2' - * - 'durationTime' was 'duratonTime' - */ - @Test - void testConvertJ2735_2016ToJ2735_2024() throws IOException, JsonUtilsException { - // prepare - String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016.json"))); - ObjectNode inputTID = JsonUtils.toObjectNode(timRequestJ2735_2016); - - // execute - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - // verify - String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json"))); - Assertions.assertEquals(expectedTID, inputTID.toString()); - } - - /** - * Test method for converting J2735-2020 ASN.1 to J2735-2024 ASN.1 - * In J2735 2020, the following fields had different names: - * - 'doNotUse1' was 'notUsed' - * - 'doNotUse2' was 'notUsed1' - * - 'doNotUse3' was 'notUsed2' - * - 'doNotUse4' was 'notUsed3' - */ - @Test - void testConvertJ2735_2020ToJ2735_2024() throws IOException, JsonUtilsException { - // prepare - String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020.json"))); - ObjectNode inputTID = JsonUtils.toObjectNode(timRequestJ2735_2016); - - // execute - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - // verify - String expectedTID = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json"))); - Assertions.assertEquals(expectedTID, inputTID.toString()); - } - } diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json deleted file mode 100644 index 397f5cdb1..000000000 --- a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2016_ConvertedToJ2735-2024.json +++ /dev/null @@ -1 +0,0 @@ -{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json deleted file mode 100644 index abb6abb0c..000000000 --- a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_J2735-2020_ConvertedToJ2735-2024.json +++ /dev/null @@ -1 +0,0 @@ -{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"durationTime":1,"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json deleted file mode 100644 index dffa502de..000000000 --- a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "request": { - "rsus": [ - { - "rsuIndex": "10", - "rsuTarget": "127.0.0.2", - "rsuUsername": "v3user", - "rsuPassword": "password", - "rsuRetries": "1", - "rsuTimeout": "1000" - } - ], - "snmp": { - "rsuid": "00000083", - "msgid": "31", - "mode": "1", - "channel": "178", - "interval": "2", - "deliverystart": "2017-06-01T17:47:11-05:00", - "deliverystop": "2018-01-01T17:47:11-05:15", - "enable": "1", - "status": "4" - } - }, - "tim": { - "msgCnt": "1", - "timeStamp": "2017-08-03T22:25:36.297Z", - "urlB": "null", - "packetID": "EC9C236B0000000000", - "dataframes": [ - { - "startDateTime": "2017-08-02T22:25:00.000Z", - "duratonTime": 1, - "sspTimRights": "0", - "frameType": "advisory", - "msgId": { - "roadSignID": { - "position": { - "latitude": "41.678473", - "longitude": "-108.782775", - "elevation": "917.1432" - }, - "viewAngle": "1010101010101010", - "mutcdCode": "warning", - "crc": "0000" - } - }, - "priority": "0", - "sspLocationRights": "0", - "regions": [ - { - "name": "Testing TIM", - "regulatorID": "0", - "segmentID": "33", - "anchorPosition": { - "latitude": "41.2500807", - "longitude": "-111.0093847", - "elevation": "2020.6969900289998" - }, - "laneWidth": "7", - "directionality": "3", - "closedPath": "false", - "description": "path", - "path": { - "scale": "0", - "type": "ll", - "nodes": [ - { - "nodeLong": "0.0002047", - "nodeLat": "-0.0002048", - "delta": "node-LL" - }, - { - "nodeLong": "0.0008191", - "nodeLat": "-0.0008192", - "delta": "node-LL" - }, - { - "nodeLong": "0.0032767", - "nodeLat": "-0.0032768", - "delta": "node-LL" - }, - { - "nodeLong": "0.0131071", - "nodeLat": "-0.0131072", - "delta": "node-LL" - }, - { - "nodeLong": "0.2097151", - "nodeLat": "-0.2097152", - "delta": "node-LL" - }, - { - "nodeLong": "0.8388607", - "nodeLat": "-0.8388608", - "delta": "node-LL" - }, - { - "nodeLong": "0.0002047", - "nodeLat": "-0.0002048", - "delta": "node-LL1" - }, - { - "nodeLong": "0.0008191", - "nodeLat": "-0.0008192", - "delta": "node-LL2" - }, - { - "nodeLong": "0.0032767", - "nodeLat": "-0.0032768", - "delta": "node-LL3" - }, - { - "nodeLong": "0.0131071", - "nodeLat": "-0.0131072", - "delta": "node-LL4" - }, - { - "nodeLong": "0.2097151", - "nodeLat": "-0.2097152", - "delta": "node-LL5" - }, - { - "nodeLong": "0.8388607", - "nodeLat": "-0.8388608", - "delta": "node-LL6" - }, - { - "nodeLong": "-111.0093847", - "nodeLat": "41.2500807", - "delta": "node-LatLon" - } - ] - }, - "direction": "0000000000001010" - } - ], - "sspMsgTypes": "2", - "sspMsgContent": "3", - "content": "Advisory", - "items": ["125","some text", "250", "'98765"], - "url": "null" - } - ] - } -} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json deleted file mode 100644 index 397f5cdb1..000000000 --- a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/builders/timRequest_pre-J2735-2016_ConvertedToJ2735-2024.json +++ /dev/null @@ -1 +0,0 @@ -{"request":{"rsus":[{"rsuIndex":"10","rsuTarget":"127.0.0.2","rsuUsername":"v3user","rsuPassword":"password","rsuRetries":"1","rsuTimeout":"1000"}],"snmp":{"rsuid":"00000083","msgid":"31","mode":"1","channel":"178","interval":"2","deliverystart":"2017-06-01T17:47:11-05:00","deliverystop":"2018-01-01T17:47:11-05:15","enable":"1","status":"4"}},"tim":{"msgCnt":"1","timeStamp":309505,"urlB":"null","packetID":"EC9C236B0000000000","dataFrames":{"TravelerDataFrame":[{"frameType":{"advisory":"EMPTY_TAG"},"msgId":{"roadSignID":{"position":{"lat":416784730,"long":-1087827750,"elevation":9171},"viewAngle":"1010101010101010","mutcdCode":{"warning":"EMPTY_TAG"},"crc":"0000"}},"priority":"0","regions":{"GeographicalPath":[{"name":"Testing TIM","laneWidth":700,"directionality":{"both":"EMPTY_TAG"},"closedPath":"BOOLEAN_OBJECT_FALSE","description":{"path":{"scale":"0","offset":{"ll":{"nodes":{"NodeLL":[{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LL1":{"lat":-2048,"lon":2047}}},{"delta":{"node-LL2":{"lat":-8192,"lon":8191}}},{"delta":{"node-LL3":{"lat":-32768,"lon":32767}}},{"delta":{"node-LL4":{"lat":-131072,"lon":131071}}},{"delta":{"node-LL5":{"lat":-2097152,"lon":2097151}}},{"delta":{"node-LL6":{"lat":-8388608,"lon":8388607}}},{"delta":{"node-LatLon":{"lat":412500807,"lon":-1110093847}}}]}}}}},"direction":"0000000000001010","id":{"region":0,"id":33},"anchor":{"lat":412500807,"long":-1110093847,"elevation":20207}}]},"url":"null","doNotUse1":0,"doNotUse2":0,"doNotUse3":0,"doNotUse4":0,"durationTime":1,"startYear":2017,"startTime":308065,"tcontent":{"advisory":{"SEQUENCE":[{"item":{"itis":125}},{"item":{"text":"some text"}},{"item":{"itis":250}},{"item":{"text":"98765"}}]}}}]}}} \ No newline at end of file From 5f3966a064bccff0cda6a026396f3da6bc4503b7 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 10:58:17 -0700 Subject: [PATCH 085/264] Fixed parameter reference in InetPacketSender --- .../src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java index bafa1d1d3..49cabf798 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java @@ -59,7 +59,7 @@ public InetPacketSender(InetPoint frwdPoint) { /** * Forward packet. Intended client is the forwarder that received a packet * - * @param inbound UDP packet + * @param packet UDP packet * @throws InetPacketException */ public void forward(DatagramPacket packet) throws InetPacketException { From 56ae0cb5fecff988112b5c3d969b213f7a9ddcc1 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 10:58:37 -0700 Subject: [PATCH 086/264] Removed unused imports --- .../us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java | 6 ------ .../TravelerMessageFromHumanToAsnConverterTest.java | 4 ---- 2 files changed, 10 deletions(-) diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java index 5a1175eab..918a55675 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -1,9 +1,7 @@ package us.dot.its.jpo.ode.model; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import java.math.BigDecimal; -import java.util.Arrays; import lombok.val; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -13,17 +11,13 @@ import us.dot.its.jpo.ode.plugin.SnmpProtocol; import us.dot.its.jpo.ode.plugin.j2735.OdePosition3D; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; -import us.dot.its.jpo.ode.plugin.j2735.builders.TravelerMessageFromHumanToAsnConverter; import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; import us.dot.its.jpo.ode.plugin.j2735.timstorage.MutcdCode; -import us.dot.its.jpo.ode.util.JsonUtils; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; -import static org.junit.jupiter.api.Assertions.*; - class OdeTravelerInputDataTest { /** diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index d93cffaf1..41fc702d5 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -16,11 +16,7 @@ package us.dot.its.jpo.ode.plugin.j2735.builders; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.val; import org.json.JSONObject; import org.json.XML; import org.junit.jupiter.api.Assertions; From c37684db159a4d572dc00224fc6bc805cb262bce Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 11:25:04 -0700 Subject: [PATCH 087/264] Updated data types in json strings in TravelerMessageFromHumanToAsnConverterTest --- ...lerMessageFromHumanToAsnConverterTest.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 41fc702d5..09553e692 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -53,7 +53,7 @@ Logger getLogger(String value) { void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -69,7 +69,7 @@ void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtils void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -85,7 +85,7 @@ void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":\"1\",\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":\"1\",\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":\"1\",\"doNotUse3\":\"1\",\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -100,7 +100,7 @@ void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { @Test void testGeometryUnavailable() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -116,7 +116,7 @@ void testGeometryUnavailable() throws JsonUtilsException { @Test void testGeometryExitServiceForward() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -132,7 +132,7 @@ void testGeometryExitServiceForward() throws JsonUtilsException { @Test void testGeometryAdvisoryReverse() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -148,7 +148,7 @@ void testGeometryAdvisoryReverse() throws JsonUtilsException { @Test void testRoadSignIDWorkzone() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -163,7 +163,7 @@ void testRoadSignIDWorkzone() throws JsonUtilsException { @Test void testGeometryBothGenericSign() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": \"0\", \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -179,7 +179,7 @@ void testGeometryBothGenericSign() throws JsonUtilsException { @Test void testPathSpeedLimit() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": \"0\", \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": \"3\", \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": \"2\", \"doNotUse3\": \"3\", \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -252,7 +252,7 @@ void testBuildItem() { @Test void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -268,7 +268,7 @@ void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { @Test void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -284,7 +284,7 @@ void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsExce @Test void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -300,7 +300,7 @@ void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsExce @Test void testOldRegionWithCircle() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( @@ -316,7 +316,7 @@ void testOldRegionWithCircle() throws JsonUtilsException { @Test void testOldRegionWithRegionPointSet() throws JsonUtilsException { ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":\"3\",\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":\"2\",\"doNotUse3\":\"3\",\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); ObjectNode expectedTID = JsonUtils.toObjectNode( From 397df56a4dd32d2c26a713ed9e6dfd3f4f83bd06 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 11:28:55 -0700 Subject: [PATCH 088/264] Modified TravelerMessageFromHumanToAsnConverter to throw exception if old fields are present --- ...ravelerMessageFromHumanToAsnConverter.java | 46 +++--- ...lerMessageFromHumanToAsnConverterTest.java | 131 ++++++++++++++++++ 2 files changed, 148 insertions(+), 29 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index d27df53c0..1a4aec269 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -133,6 +133,11 @@ private TravelerMessageFromHumanToAsnConverter() { super(); } + /** + * Converts a TravelerInputData object to a TIM object + * @param tid TravelerInputData object serialized as a JsonNode + * @throws JsonUtilsException if there is an issue converting the JsonNode + */ public static void convertTravelerInputDataToEncodableTim(JsonNode tid) throws JsonUtilsException { // msgCnt MsgCount, // timeStamp MinuteOfTheYear OPTIONAL @@ -1099,37 +1104,20 @@ private static String nodeOffsetPointXY(long transformedX, long transformedY) { } /** - * Ensures compliance with the J2735 2024 by modifying the given data frame. + * Ensures compliance with the J2735 2024 standard by checking for old fields in the given data frame. * - * @param dataFrame the JSON object representing the data frame to be modified + * @param dataFrame the JSON object representing the data frame to be checked + * @throws IllegalArgumentException if any old fields are found */ - private static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { - // Remove fields from before J2735 2016 - dataFrame.remove(SSP_MSG_CONTENT); // renamed to sspMsgRights1 - dataFrame.remove(SSP_MSG_TYPES); // renamed to sspMsgRights2 - - // Remove J2735 2016 fields - dataFrame.remove(SSP_TIM_RIGHTS); // renamed to notUsed in J2735 2020 - dataFrame.remove(SSP_LOCATION_RIGHTS); // renamed to notUsed1 in J2735 2020 - dataFrame.remove(SSP_MSG_RIGHTS_1); // renamed to notUsed2 in J2735 2020 - dataFrame.remove(SSP_MSG_RIGHTS_2); // renamed to notUsed3 in J2735 2020 - - // Remove J2735 2020 fields - dataFrame.remove(NOT_USED); // renamed to doNotUse1 in J2735 2024 - dataFrame.remove(NOT_USED_1); // renamed to doNotUse2 in J2735 2024 - dataFrame.remove(NOT_USED_2); // renamed to doNotUse3 in J2735 2024 - dataFrame.remove(NOT_USED_3); // renamed to doNotUse4 in J2735 2024 - - // Add J2735 2024 fields with values of 0 - dataFrame.put(DO_NOT_USE_1, 0); - dataFrame.put(DO_NOT_USE_2, 0); - dataFrame.put(DO_NOT_USE_3, 0); - dataFrame.put(DO_NOT_USE_4, 0); - - // Replace misspelled durationTime field from J2735 2016 with the correct one - if (dataFrame.get(DURATON_TIME_MISSPELLED) != null) { - dataFrame.set(DURATION_TIME, dataFrame.get(DURATON_TIME_MISSPELLED)); - dataFrame.remove(DURATON_TIME_MISSPELLED); + public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { + // Check and throw exception if old fields are found + if (dataFrame.has(SSP_MSG_CONTENT) || dataFrame.has(SSP_MSG_TYPES) || + dataFrame.has(SSP_TIM_RIGHTS) || dataFrame.has(SSP_LOCATION_RIGHTS) || + dataFrame.has(SSP_MSG_RIGHTS_1) || dataFrame.has(SSP_MSG_RIGHTS_2) || + dataFrame.has(NOT_USED) || dataFrame.has(NOT_USED_1) || + dataFrame.has(NOT_USED_2) || dataFrame.has(NOT_USED_3) || + dataFrame.has(DURATON_TIME_MISSPELLED)) { + throw new IllegalArgumentException("Data frame contains old fields that are not compliant with J2735 2024. Deserialization should prevent this."); } } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 09553e692..4c4a49a80 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -15,6 +15,9 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.builders; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.fasterxml.jackson.databind.node.JsonNodeFactory; import java.io.IOException; import org.json.JSONObject; @@ -329,4 +332,132 @@ void testOldRegionWithRegionPointSet() throws JsonUtilsException { Assertions.assertNotNull(XML.toString(timObject)); } + @Test + void ensureComplianceWithJ2735Revision2024_noOldFields() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("doNotUse1", 0); + dataFrame.put("doNotUse2", 0); + dataFrame.put("doNotUse3", 0); + dataFrame.put("doNotUse4", 0); + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgContent() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgContent", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgTypes() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgTypes", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspTimRights() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspTimRights", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspLocationRights() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspLocationRights", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights1() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgRights1", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights2() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgRights2", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed1() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed1", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed2() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed2", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed3() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed3", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_duratonTime() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("duratonTime", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsMultipleOldFields() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgContent", 1); + dataFrame.put("sspMsgTypes", 1); + dataFrame.put("sspTimRights", 1); + dataFrame.put("sspLocationRights", 1); + dataFrame.put("sspMsgRights1", 1); + dataFrame.put("sspMsgRights2", 1); + dataFrame.put("notUsed", 1); + dataFrame.put("notUsed1", 1); + dataFrame.put("notUsed2", 1); + dataFrame.put("notUsed3", 1); + dataFrame.put("duratonTime", 1); + assertThrows(IllegalArgumentException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + } From 07ab12d435605c56e622d8c7bddf2512ac6d365d Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 1 Dec 2024 11:37:06 -0700 Subject: [PATCH 089/264] Updated major version to 4 due to breaking changes with J2735 2024 --- jpo-ode-common/pom.xml | 2 +- jpo-ode-core/pom.xml | 6 +++--- jpo-ode-plugins/pom.xml | 4 ++-- jpo-ode-svcs/pom.xml | 6 +++--- jpo-ode-svcs/run.bat | 2 +- jpo-ode-svcs/run.sh | 2 +- pom.xml | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/jpo-ode-common/pom.xml b/jpo-ode-common/pom.xml index 7ba82c8d5..e91045b8f 100644 --- a/jpo-ode-common/pom.xml +++ b/jpo-ode-common/pom.xml @@ -5,7 +5,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT jpo-ode-common diff --git a/jpo-ode-core/pom.xml b/jpo-ode-core/pom.xml index 638e02106..fe0b49f86 100644 --- a/jpo-ode-core/pom.xml +++ b/jpo-ode-core/pom.xml @@ -5,7 +5,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT jpo-ode-core @@ -23,12 +23,12 @@ usdot.jpo.ode jpo-ode-common - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT usdot.jpo.ode jpo-ode-plugins - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT org.apache.httpcomponents diff --git a/jpo-ode-plugins/pom.xml b/jpo-ode-plugins/pom.xml index 50b5281d1..485792bc7 100644 --- a/jpo-ode-plugins/pom.xml +++ b/jpo-ode-plugins/pom.xml @@ -11,7 +11,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT @@ -27,7 +27,7 @@ usdot.jpo.ode jpo-ode-common - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT + 4.0.0-SNAPSHOT ${project.build.directory}/${project.artifactId}-${project.version} ${maven.build.timestamp} yyyy-MM-dd'T'HH:mm:ss.SSSZ From b94e5d00013a712b47a00b0a431c4489c9a6adbb Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 2 Dec 2024 13:34:22 -0700 Subject: [PATCH 104/264] Reverted changes to pom.xml --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 5882ee704..ce2b70dfd 100644 --- a/pom.xml +++ b/pom.xml @@ -11,12 +11,12 @@ scm:git:https://github.com/usdot-jpo-ode/jpo-ode.git - jpo-ode-${project.ode.version} + jpo-ode-4.0.0-SNAPSHOT usdot.jpo.ode jpo-ode - ${project.ode.version} + 4.0.0-SNAPSHOT pom jpo-ode-common @@ -31,7 +31,6 @@ 21 - 4.0.0-SNAPSHOT ${project.build.directory}/${project.artifactId}-${project.version} ${maven.build.timestamp} yyyy-MM-dd'T'HH:mm:ss.SSSZ From af8d0d0b3e41fbbe90c9bedb361fc356d4df9938 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 2 Dec 2024 14:06:29 -0700 Subject: [PATCH 105/264] Added `@JsonAlias` and `@EqualsAndHashCode` annotations to TravelerDataFrame --- .../ode/plugin/j2735/timstorage/Anchor.java | 2 + .../jpo/ode/plugin/j2735/timstorage/Area.java | 2 + .../ode/plugin/j2735/timstorage/Circle.java | 2 + .../plugin/j2735/timstorage/ComputedLane.java | 2 + .../ode/plugin/j2735/timstorage/Content.java | 2 + .../plugin/j2735/timstorage/Description.java | 2 + .../j2735/timstorage/DirectionOfUse.java | 2 + .../j2735/timstorage/DistanceUnits.java | 2 + .../ode/plugin/j2735/timstorage/Extent.java | 2 + .../plugin/j2735/timstorage/FrameType.java | 2 + .../j2735/timstorage/GeographicalPath.java | 69 +------------------ .../j2735/timstorage/GeometricProjection.java | 2 + .../jpo/ode/plugin/j2735/timstorage/Id.java | 2 + .../j2735/timstorage/LaneDataAttribute.java | 2 + .../timstorage/LaneDataAttributeList.java | 2 + .../ode/plugin/j2735/timstorage/MsgId.java | 2 + .../j2735/timstorage/NodeAttributeSetXY.java | 2 + .../ode/plugin/j2735/timstorage/NodeLL.java | 2 + .../plugin/j2735/timstorage/NodeListLL.java | 2 + .../plugin/j2735/timstorage/NodeListXY.java | 2 + .../j2735/timstorage/NodeOffsetPointXY.java | 2 + .../plugin/j2735/timstorage/NodeSetXY.java | 2 + .../ode/plugin/j2735/timstorage/NodeXY.java | 2 + .../ode/plugin/j2735/timstorage/Node_XY.java | 2 + .../ode/plugin/j2735/timstorage/Nodes.java | 2 + .../ode/plugin/j2735/timstorage/Offset.java | 2 + .../plugin/j2735/timstorage/OffsetAxis.java | 2 + .../plugin/j2735/timstorage/OffsetSystem.java | 2 + .../ode/plugin/j2735/timstorage/Position.java | 2 + .../plugin/j2735/timstorage/RegionList.java | 2 + .../j2735/timstorage/RegionOffsets.java | 2 + .../j2735/timstorage/RegionPointSet.java | 2 + .../ode/plugin/j2735/timstorage/Regions.java | 2 + .../timstorage/RegulatorySpeedLimit.java | 2 + .../j2735/timstorage/ShapePointSet.java | 2 + .../j2735/timstorage/SpeedLimitList.java | 2 + .../j2735/timstorage/SpeedLimitType.java | 2 + .../j2735/timstorage/TravelerDataFrame.java | 21 +++--- .../plugin/j2735/timstorage/ValidRegion.java | 2 + .../timstorage/TravelerDataFrameTest.java | 63 +++++++++++++++++ .../travelerDataFrame_J2735-2016.json | 15 ++++ .../travelerDataFrame_J2735-2020.json | 15 ++++ .../travelerDataFrame_pre-J2735-2016.json | 15 ++++ 43 files changed, 192 insertions(+), 80 deletions(-) create mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json create mode 100644 jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java index e2f56d73c..7bb4b138f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java @@ -18,9 +18,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonPropertyOrder({ "lat", "long", "elevation" }) +@EqualsAndHashCode(callSuper = false) public class Anchor extends Asn1Object { private static final long serialVersionUID = 1L; private String lat; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java index 7670b0391..8d3b70796 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Area extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java index 90c5e130e..9690a9d53 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java @@ -18,9 +18,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonPropertyOrder({ "center", "radius", "units" }) +@EqualsAndHashCode(callSuper = false) public class Circle extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java index 078964e9c..f4378731d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class ComputedLane extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java index 58d199c2d..6d030422c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Content extends Asn1Object { private static final long serialVersionUID = 1L; private ITIS_CodesAndText advisory; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java index b19b0160b..28ebc62f9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Description extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java index ef640201c..1947087de 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class DirectionOfUse extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java index 954673236..35f1232d0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class DistanceUnits extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java index 866baff20..bf24a9af1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Extent extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java index 408af840b..2438c1523 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class FrameType extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java index fe0c7e783..b3123f274 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java @@ -18,9 +18,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonPropertyOrder({ "name", "id", "anchor", "laneWidth", "directionality", "closedPath", "direction", "description" }) +@EqualsAndHashCode(callSuper = false) public class GeographicalPath extends Asn1Object { private static final long serialVersionUID = 1L; @@ -112,71 +114,4 @@ public Anchor getAnchor() { public void setAnchor(Anchor anchor) { this.anchor = anchor; } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((anchor == null) ? 0 : anchor.hashCode()); - result = prime * result + ((closedPath == null) ? 0 : closedPath.hashCode()); - result = prime * result + ((description == null) ? 0 : description.hashCode()); - result = prime * result + ((direction == null) ? 0 : direction.hashCode()); - result = prime * result + ((directionality == null) ? 0 : directionality.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((laneWidth == null) ? 0 : laneWidth.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - GeographicalPath other = (GeographicalPath) obj; - if (anchor == null) { - if (other.anchor != null) - return false; - } else if (!anchor.equals(other.anchor)) - return false; - if (closedPath == null) { - if (other.closedPath != null) - return false; - } else if (!closedPath.equals(other.closedPath)) - return false; - if (description == null) { - if (other.description != null) - return false; - } else if (!description.equals(other.description)) - return false; - if (direction == null) { - if (other.direction != null) - return false; - } else if (!direction.equals(other.direction)) - return false; - if (directionality == null) { - if (other.directionality != null) - return false; - } else if (!directionality.equals(other.directionality)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (laneWidth == null) { - if (other.laneWidth != null) - return false; - } else if (!laneWidth.equals(other.laneWidth)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - return true; - } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java index fcedada6b..626531508 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java @@ -18,9 +18,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonPropertyOrder({ "direction", "extent", "laneWidth", "circle" }) +@EqualsAndHashCode(callSuper = false) public class GeometricProjection extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java index 03671bd51..df4815bec 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Id extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java index 18ffbd306..63db41830 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class LaneDataAttribute extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java index 2cff56126..8ab281128 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class LaneDataAttributeList extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java index 0f043c2b7..f79da2f7f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class MsgId extends Asn1Object { private static final long serialVersionUID = 1L; private RoadSignID roadSignID; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java index 683c72ea0..bdb879636 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeAttributeSetXY extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java index 0ea3c80e6..3a0545c09 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeLL extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java index e341cf260..4ff06599d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeListLL extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java index 1310da0ad..41a2d9387 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeListXY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java index dc380935b..5f40820d0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java @@ -17,8 +17,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeOffsetPointXY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java index 4980d6304..2a731532e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeSetXY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java index 1b8a3f238..a472f9410 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class NodeXY extends Asn1Object { private static final long serialVersionUID = 1L; private NodeOffsetPointXY delta; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java index 6c0163d46..99d22af65 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Node_XY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java index 5a86763fa..33ed12add 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java @@ -17,8 +17,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Nodes extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java index e17a6a3b0..da359618c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Offset extends Asn1Object { private static final long serialVersionUID = 1L; private NodeListLL ll; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java index dadd10331..9441fa25d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class OffsetAxis extends Asn1Object { private static final long serialVersionUID = 7703530986729802700L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java index 2c6a3dd0f..926810005 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java @@ -15,8 +15,10 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class OffsetSystem extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java index d38a61d4b..81507aabd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java @@ -19,10 +19,12 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonIgnoreProperties(ignoreUnknown = true) @JsonPropertyOrder({ "lat", "llong", "elevation" }) +@EqualsAndHashCode(callSuper = false) public class Position extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java index f7c0c84bd..221d468a9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class RegionList extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java index 1e7da580e..aff1f37dd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class RegionOffsets extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java index 3e6febdfb..f80c56793 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class RegionPointSet extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java index 54cf8cdbd..513f2c6be 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java @@ -17,8 +17,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class Regions extends Asn1Object { private static final long serialVersionUID = 1L; private GeographicalPath[] GeographicalPath; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java index aa2b2ee7d..bb705e2a4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class RegulatorySpeedLimit extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java index 7e364c73a..b7359e1ee 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class ShapePointSet extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java index f1d4046ab..e0c64711c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class SpeedLimitList extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java index 23ffc939c..9d8af8d2c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class SpeedLimitType extends Asn1Object { /** diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java index 452f5171f..e2948257d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java @@ -15,42 +15,37 @@ ******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonPropertyOrder({ "doNotUse1", "frameType", "msgId", "startYear", "startTime", "durationTime", "priority", "doNotUse2", "regions", "doNotUse3", "doNotUse4", "tcontent", "url" }) +@EqualsAndHashCode(callSuper = false) public class TravelerDataFrame extends Asn1Object { private static final long serialVersionUID = 1L; - + @JsonAlias({"sspTimRights", "notUsed"}) private String doNotUse1; - private FrameType frameType; - private MsgId msgId; - private String startYear; - private String startTime; - + @JsonAlias("duratonTime") private String durationTime; - private String priority; - + @JsonAlias({"sspLocationRights", "notUsed1"}) private String doNotUse2; - private Regions regions; - + @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) private String doNotUse3; - + @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) private String doNotUse4; - @JsonProperty("tcontent") private Content tcontent; - private String url; public String getDoNotUse2() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java index 1add35ac1..dfc0b22bd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java @@ -1,7 +1,9 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +@EqualsAndHashCode(callSuper = false) public class ValidRegion extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java new file mode 100644 index 000000000..122b5a989 --- /dev/null +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java @@ -0,0 +1,63 @@ +package us.dot.its.jpo.ode.plugin.j2735.timstorage; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +class TravelerDataFrameTest { + + @Test + void deserializePreJ2735_2016() throws IOException { + String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); + + TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); + + Assertions.assertEquals(expectedFrame, deserializedFrame); + } + + @Test + void deserializeJ2735_2016() throws IOException { + String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); + + TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); + + Assertions.assertEquals(expectedFrame, deserializedFrame); + } + + @Test + void deserializeJ2735_2020() throws IOException { + String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json"))); + ObjectMapper mapper = new ObjectMapper(); + TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); + + TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); + + Assertions.assertEquals(expectedFrame, deserializedFrame); + } + + private TravelerDataFrame getExpectedTravelerDataFrame() { + TravelerDataFrame frame = new TravelerDataFrame(); + frame.setDoNotUse1("value1"); + frame.setFrameType(new FrameType()); + frame.setMsgId(new MsgId()); + frame.setStartYear("2024"); + frame.setStartTime("12:00"); + frame.setDurationTime("30"); + frame.setPriority("high"); + frame.setDoNotUse2("value2"); + frame.setRegions(new Regions()); + frame.setDoNotUse3("value3"); + frame.setDoNotUse4("value4"); + frame.setTcontent(new Content()); + frame.setUrl("http://example.com"); + return frame; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json new file mode 100644 index 000000000..de5fe041a --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json @@ -0,0 +1,15 @@ +{ + "startYear": "2024", + "startTime": "12:00", + "duratonTime": "30", + "sspTimRights": "value1", + "frameType": {}, + "msgId": {}, + "priority": "high", + "sspLocationRights": "value2", + "regions": {}, + "sspMsgContent": "value3", + "sspMsgTypes": "value4", + "tcontent": {}, + "url": "http://example.com" +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json new file mode 100644 index 000000000..de5fe041a --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json @@ -0,0 +1,15 @@ +{ + "startYear": "2024", + "startTime": "12:00", + "duratonTime": "30", + "sspTimRights": "value1", + "frameType": {}, + "msgId": {}, + "priority": "high", + "sspLocationRights": "value2", + "regions": {}, + "sspMsgContent": "value3", + "sspMsgTypes": "value4", + "tcontent": {}, + "url": "http://example.com" +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json new file mode 100644 index 000000000..de5fe041a --- /dev/null +++ b/jpo-ode-plugins/src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json @@ -0,0 +1,15 @@ +{ + "startYear": "2024", + "startTime": "12:00", + "duratonTime": "30", + "sspTimRights": "value1", + "frameType": {}, + "msgId": {}, + "priority": "high", + "sspLocationRights": "value2", + "regions": {}, + "sspMsgContent": "value3", + "sspMsgTypes": "value4", + "tcontent": {}, + "url": "http://example.com" +} \ No newline at end of file From 82bd2a7042f30b60d184926af2820a6edf8a0073 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 2 Dec 2024 14:15:22 -0700 Subject: [PATCH 106/264] Formatted aemInputContainingCircleGeometry.xml for ease of review & updated related unit test --- .../ode/traveler/TimTransmogrifierTest.java | 4 +- .../aemInputContainingCircleGeometry.xml | 146 +++++++++++++++++- 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index b24dbb2ec..a7d52097c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -280,7 +280,9 @@ void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() t String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); // verify - String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))); + String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))) + .replaceAll("\\s", "") // remove all whitespace + .replaceAll("", ""); // add space before closing tag Assertions.assertEquals(expectedXml, actualXML); } diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml index cbaa4ab30..125c29aa5 100644 --- a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml @@ -1 +1,145 @@ -us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPERMessageFrame3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000
411535930-104655785018240
50
004868null
\ No newline at end of file + + + us.dot.its.jpo.ode.model.OdeTimPayload + + testStreamId + 1 + 0 + 0 + 0 + + 2024-11-05T16:51:14.473Z + 7 + 8640 + 2024-09-25T10:00:00.000Z + TMC + false + 8D442FF4020C6B1A01 + 2024-09-25T10:00:00.000Z + + + 3 + PUT + + + + 172.0.0.1 + username + password + 3 + 5000 + 21 + NTCIP1218 + + + + 83 + 31 + 1 + 183 + 1000 + 2024-09-25T10:00:00.0Z + 2024-09-30T10:00:00.0Z + 1 + 4 + + + + + MessageFrame + MessageFrame + UPER + + + + + MessageFrame + + + 31 + + + 1 + 386520 + 8D442FF4020C6B1A01 + null + + + 0 + + + + + + + 411535930 + -1046557850 + + 1111111111111111 + + + + + + 2024 + 386520 + 8640 + 5 + 0 + + + myregionname + + 0 + 0 + + + 411535930 + -1046557850 + + + + + + + + 1111000011110000 + + + 1111000011110000 + 0 + +
+ 411535930 + -1046557850 + 18240 +
+ 50 + + + +
+
+
+
+
+ 0 + 0 + + + + + 4868 + + + + + null +
+
+
+
+
+
+
+
\ No newline at end of file From 595f47c1890f07f26da86400b3e2e615c682fff0 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 2 Dec 2024 16:54:10 -0700 Subject: [PATCH 107/264] Remove the array from the computed lane --- .../jpo/ode/plugin/j2735/J2735NodeListXY.java | 6 ++-- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 34 +++++++++++-------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java index d0e2555c1..5d3d493d0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListXY.java @@ -8,7 +8,7 @@ public class J2735NodeListXY extends Asn1Object { */ private static final long serialVersionUID = 1L; private J2735NodeXY[] nodes; - private J2735ComputedLane[] computed; + private J2735ComputedLane computed; public J2735NodeXY[] getNodes() { return nodes; @@ -18,11 +18,11 @@ public void setNodes(J2735NodeXY[] nodes) { this.nodes = nodes; } - public J2735ComputedLane[] getComputed() { + public J2735ComputedLane getComputed() { return computed; } - public void setComputed(J2735ComputedLane[] computed) { + public void setComputed(J2735ComputedLane computed) { this.computed = computed; } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index 76ebb2197..937ddf8b1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -11,19 +11,18 @@ import org.apache.kafka.streams.state.QueryableStoreTypes; import org.apache.kafka.streams.state.Stores; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; - import java.util.Properties; - /** * The OdeTimJsonTopology class sets up and manages a Kafka Streams topology - * for processing TIM (Traveler Information Message) JSON data from the OdeTimJson Kafka topic. - * This class creates a K-Table that houses TMC-generated TIMs which can be queried by UUID. + * for processing TIM (Traveler Information Message) JSON data from the + * OdeTimJson Kafka topic. + * This class creates a K-Table that houses TMC-generated TIMs which can be + * queried by UUID. **/ @Slf4j public class OdeTimJsonTopology { - private final Properties streamsProperties = new Properties(); static KafkaStreams streams; @@ -33,12 +32,12 @@ public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps) { this.streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); this.streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass()); this.streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass()); - + String kafkaType = System.getenv("KAFKA_TYPE"); if (kafkaType != null && kafkaType.equals("CONFLUENT")) { addConfluentProperties(this.streamsProperties); - } - } else { + } + } else { log.error("Kafka Brokers not set in OdeProperties"); } } @@ -68,12 +67,17 @@ public boolean isRunning() { public Topology buildTopology() { StreamsBuilder builder = new StreamsBuilder(); - builder.table("topic.OdeTimJson", Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); + builder.table("topic.OdeTimJson", + Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); return builder.build(); } public String query(String uuid) { - return (String) streams.store(StoreQueryParameters.fromNameAndType("timjson-store", QueryableStoreTypes.keyValueStore())).get(uuid); + return (String) streams.store( + StoreQueryParameters.fromNameAndType( + "timjson-store", + QueryableStoreTypes.keyValueStore())) + .get(uuid); } private void addConfluentProperties(Properties properties) { @@ -82,12 +86,12 @@ private void addConfluentProperties(Properties properties) { if (username != null && password != null) { String auth = "org.apache.kafka.common.security.plain.PlainLoginModule required " + - "username=\"" + username + "\" " + - "password=\"" + password + "\";"; + "username=\"" + username + "\" " + + "password=\"" + password + "\";"; this.streamsProperties.put("sasl.jaas.config", auth); - } - else { - log.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); + } else { + log.error( + "Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud"); } } } From f3d5cf6d2acfe93a3c7ede0dda7747385b3a6601 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Tue, 3 Dec 2024 03:14:44 -0700 Subject: [PATCH 108/264] Add dynamic serializing and deserializing of TIM messages with new dynamically created POJOs --- .../us/dot/its/jpo/ode/util/XmlUtils.java | 25 ++ .../dot/its/jpo/ode/model/OdeTimPayload.java | 4 +- .../annotations/Asn1ParameterizedTypes.java | 65 ++++ .../ode/plugin/annotations/Asn1Property.java | 47 +++ .../ode/plugin/annotations/package-info.java | 4 + .../ode/plugin/j2735/AddGrpB/DegreesLat.java | 46 +++ .../ode/plugin/j2735/AddGrpB/DegreesLong.java | 46 +++ .../ode/plugin/j2735/AddGrpB/Elevation.java | 46 +++ .../AddGrpB/LaneDataAttribute_addGrpB.java | 32 ++ ...ttribute_addGrpBReg_LaneDataAttribute.java | 43 +++ ...eg_LaneDataAttributeValueDeserializer.java | 29 ++ ...BReg_LaneDataAttributeValueSerializer.java | 29 ++ .../ode/plugin/j2735/AddGrpB/LatitudeDMS.java | 46 +++ .../plugin/j2735/AddGrpB/LatitudeDMS2.java | 68 ++++ .../plugin/j2735/AddGrpB/LongitudeDMS.java | 46 +++ .../plugin/j2735/AddGrpB/LongitudeDMS2.java | 68 ++++ .../plugin/j2735/AddGrpB/MinutesAngle.java | 46 +++ .../AddGrpB/NodeOffsetPointXY_addGrpB.java | 60 +++ ...tPointXY_addGrpBReg_NodeOffsetPointXY.java | 43 +++ ...eg_NodeOffsetPointXYValueDeserializer.java | 29 ++ ...BReg_NodeOffsetPointXYValueSerializer.java | 29 ++ .../plugin/j2735/AddGrpB/Node_LLdms_48b.java | 57 +++ .../plugin/j2735/AddGrpB/Node_LLdms_80b.java | 54 +++ .../j2735/AddGrpB/Position3D_addGrpB.java | 66 ++++ .../Position3D_addGrpBReg_Position3D.java | 43 +++ ...ddGrpBReg_Position3DValueDeserializer.java | 27 ++ ..._addGrpBReg_Position3DValueSerializer.java | 27 ++ .../plugin/j2735/AddGrpB/SecondsAngle.java | 46 +++ .../ode/plugin/j2735/AddGrpC/Altitude.java | 56 +++ .../j2735/AddGrpC/AltitudeConfidence.java | 57 +++ .../AltitudeConfidenceDeserializer.java | 32 ++ .../AddGrpC/AltitudeConfidenceSerializer.java | 27 ++ .../plugin/j2735/AddGrpC/AltitudeValue.java | 46 +++ .../j2735/AddGrpC/Position3D_addGrpC.java | 44 +++ .../Position3D_addGrpCReg_Position3D.java | 43 +++ ...ddGrpCReg_Position3DValueDeserializer.java | 27 ++ ..._addGrpCReg_Position3DValueSerializer.java | 27 ++ .../its/jpo/ode/plugin/j2735/DSRC/Angle.java | 46 +++ .../its/jpo/ode/plugin/j2735/DSRC/Circle.java | 66 ++++ .../ode/plugin/j2735/DSRC/ComputedLane.java | 192 ++++++++++ .../its/jpo/ode/plugin/j2735/DSRC/DYear.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/DeltaAngle.java | 46 +++ .../plugin/j2735/DSRC/DescriptiveName.java | 34 ++ .../ode/plugin/j2735/DSRC/DirectionOfUse.java | 52 +++ .../DSRC/DirectionOfUseDeserializer.java | 32 ++ .../j2735/DSRC/DirectionOfUseSerializer.java | 27 ++ .../ode/plugin/j2735/DSRC/DistanceUnits.java | 53 +++ .../j2735/DSRC/DistanceUnitsDeserializer.java | 32 ++ .../j2735/DSRC/DistanceUnitsSerializer.java | 27 ++ .../plugin/j2735/DSRC/DrivenLineOffsetLg.java | 46 +++ .../plugin/j2735/DSRC/DrivenLineOffsetSm.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Elevation.java | 46 +++ .../ode/plugin/j2735/DSRC/ExitService.java | 30 ++ .../j2735/DSRC/ExitServiceSequence.java | 84 +++++ .../its/jpo/ode/plugin/j2735/DSRC/Extent.java | 62 +++ .../plugin/j2735/DSRC/ExtentDeserializer.java | 32 ++ .../plugin/j2735/DSRC/ExtentSerializer.java | 27 ++ .../ode/plugin/j2735/DSRC/FurtherInfoID.java | 49 +++ .../ode/plugin/j2735/DSRC/GenericSignage.java | 30 ++ .../j2735/DSRC/GenericSignageSequence.java | 84 +++++ .../plugin/j2735/DSRC/GeographicalPath.java | 183 +++++++++ .../j2735/DSRC/GeometricProjection.java | 95 +++++ .../ode/plugin/j2735/DSRC/HeadingSlice.java | 163 ++++++++ .../j2735/DSRC/HeadingSliceDeserializer.java | 32 ++ .../ode/plugin/j2735/DSRC/ITIStextPhrase.java | 34 ++ .../plugin/j2735/DSRC/LaneDataAttribute.java | 129 +++++++ .../j2735/DSRC/LaneDataAttributeList.java | 30 ++ .../its/jpo/ode/plugin/j2735/DSRC/LaneID.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/LaneWidth.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Latitude.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Longitude.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/MUTCDCode.java | 53 +++ .../j2735/DSRC/MUTCDCodeDeserializer.java | 32 ++ .../j2735/DSRC/MUTCDCodeSerializer.java | 27 ++ .../j2735/DSRC/MergeDivergeNodeAngle.java | 46 +++ .../plugin/j2735/DSRC/MinuteOfTheYear.java | 46 +++ .../plugin/j2735/DSRC/MinutesDuration.java | 46 +++ .../its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java | 49 +++ .../jpo/ode/plugin/j2735/DSRC/MsgCount.java | 46 +++ .../plugin/j2735/DSRC/NodeAttributeLL.java | 56 +++ .../DSRC/NodeAttributeLLDeserializer.java | 32 ++ .../j2735/DSRC/NodeAttributeLLList.java | 49 +++ .../j2735/DSRC/NodeAttributeLLSerializer.java | 27 ++ .../plugin/j2735/DSRC/NodeAttributeSetLL.java | 121 ++++++ .../plugin/j2735/DSRC/NodeAttributeSetXY.java | 121 ++++++ .../plugin/j2735/DSRC/NodeAttributeXY.java | 56 +++ .../DSRC/NodeAttributeXYDeserializer.java | 32 ++ .../j2735/DSRC/NodeAttributeXYList.java | 49 +++ .../j2735/DSRC/NodeAttributeXYSerializer.java | 27 ++ .../its/jpo/ode/plugin/j2735/DSRC/NodeLL.java | 54 +++ .../jpo/ode/plugin/j2735/DSRC/NodeListLL.java | 54 +++ .../jpo/ode/plugin/j2735/DSRC/NodeListXY.java | 64 ++++ .../plugin/j2735/DSRC/NodeOffsetPointLL.java | 129 +++++++ .../plugin/j2735/DSRC/NodeOffsetPointXY.java | 129 +++++++ .../jpo/ode/plugin/j2735/DSRC/NodeSetLL.java | 30 ++ .../jpo/ode/plugin/j2735/DSRC/NodeSetXY.java | 30 ++ .../its/jpo/ode/plugin/j2735/DSRC/NodeXY.java | 54 +++ .../ode/plugin/j2735/DSRC/Node_LL_24B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LL_28B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LL_32B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LL_36B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LL_44B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LL_48B.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_LLmD_64b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_20b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_22b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_24b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_26b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_28b.java | 57 +++ .../ode/plugin/j2735/DSRC/Node_XY_32b.java | 57 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B12.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B14.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B16.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B18.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B22.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetLL_B24.java | 46 +++ .../ode/plugin/j2735/DSRC/OffsetSystem.java | 93 +++++ .../jpo/ode/plugin/j2735/DSRC/Offset_B10.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Offset_B11.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Offset_B12.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Offset_B13.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Offset_B14.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Offset_B16.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Position3D.java | 89 +++++ .../jpo/ode/plugin/j2735/DSRC/Radius_B12.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/RegionId.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/RegionList.java | 30 ++ .../ode/plugin/j2735/DSRC/RegionOffsets.java | 68 ++++ .../ode/plugin/j2735/DSRC/RegionPointSet.java | 70 ++++ .../plugin/j2735/DSRC/RegionalExtension.java | 63 ++++ .../j2735/DSRC/RegulatorySpeedLimit.java | 56 +++ .../plugin/j2735/DSRC/RoadRegulatorID.java | 46 +++ .../ode/plugin/j2735/DSRC/RoadSegmentID.java | 46 +++ .../j2735/DSRC/RoadSegmentReferenceID.java | 57 +++ .../jpo/ode/plugin/j2735/DSRC/RoadSignID.java | 74 ++++ .../plugin/j2735/DSRC/RoadwayCrownAngle.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/SSPindex.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/Scale_B12.java | 46 +++ .../plugin/j2735/DSRC/SegmentAttributeLL.java | 104 +++++ .../DSRC/SegmentAttributeLLDeserializer.java | 32 ++ .../j2735/DSRC/SegmentAttributeLLList.java | 49 +++ .../DSRC/SegmentAttributeLLSerializer.java | 27 ++ .../plugin/j2735/DSRC/SegmentAttributeXY.java | 104 +++++ .../DSRC/SegmentAttributeXYDeserializer.java | 32 ++ .../j2735/DSRC/SegmentAttributeXYList.java | 49 +++ .../DSRC/SegmentAttributeXYSerializer.java | 27 ++ .../ode/plugin/j2735/DSRC/ShapePointSet.java | 76 ++++ .../ode/plugin/j2735/DSRC/SignPrority.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/SpeedLimit.java | 30 ++ .../ode/plugin/j2735/DSRC/SpeedLimitList.java | 30 ++ .../plugin/j2735/DSRC/SpeedLimitSequence.java | 84 +++++ .../ode/plugin/j2735/DSRC/SpeedLimitType.java | 60 +++ .../DSRC/SpeedLimitTypeDeserializer.java | 32 ++ .../j2735/DSRC/SpeedLimitTypeSerializer.java | 27 ++ .../plugin/j2735/DSRC/TravelerDataFrame.java | 355 ++++++++++++++++++ .../j2735/DSRC/TravelerDataFrameList.java | 30 ++ .../plugin/j2735/DSRC/TravelerInfoType.java | 53 +++ .../DSRC/TravelerInfoTypeDeserializer.java | 32 ++ .../DSRC/TravelerInfoTypeSerializer.java | 27 ++ .../j2735/DSRC/TravelerInformation.java | 111 ++++++ .../jpo/ode/plugin/j2735/DSRC/URL_Base.java | 34 ++ .../jpo/ode/plugin/j2735/DSRC/URL_Short.java | 34 ++ .../ode/plugin/j2735/DSRC/UniqueMSGID.java | 49 +++ .../ode/plugin/j2735/DSRC/ValidRegion.java | 111 ++++++ .../jpo/ode/plugin/j2735/DSRC/Velocity.java | 46 +++ .../jpo/ode/plugin/j2735/DSRC/WorkZone.java | 30 ++ .../plugin/j2735/DSRC/WorkZoneSequence.java | 84 +++++ .../its/jpo/ode/plugin/j2735/DSRC/Zoom.java | 46 +++ .../jpo/ode/plugin/j2735/ITIS/ITIScodes.java | 46 +++ .../plugin/j2735/ITIS/ITIScodesAndText.java | 30 ++ .../j2735/ITIS/ITIScodesAndTextSequence.java | 83 ++++ .../jpo/ode/plugin/j2735/ITIS/ITIStext.java | 34 ++ .../plugin/j2735/REGION/Reg_ComputedLane.java | 30 ++ .../j2735/REGION/Reg_GeographicalPath.java | 30 ++ .../j2735/REGION/Reg_GeometricProjection.java | 30 ++ .../j2735/REGION/Reg_LaneDataAttribute.java | 41 ++ .../j2735/REGION/Reg_NodeAttributeSetLL.java | 30 ++ .../j2735/REGION/Reg_NodeAttributeSetXY.java | 30 ++ .../j2735/REGION/Reg_NodeOffsetPointLL.java | 30 ++ .../j2735/REGION/Reg_NodeOffsetPointXY.java | 41 ++ .../plugin/j2735/REGION/Reg_Position3D.java | 42 +++ .../j2735/REGION/Reg_TravelerInformation.java | 30 ++ .../j2735/builders/NodeListXYBuilder.java | 16 +- .../serialization/BitStringDeserializer.java | 39 ++ .../serialization/BitstringSerializer.java | 31 ++ .../serialization/BooleanDeserializer.java | 45 +++ .../serialization/BooleanSerializer.java | 29 ++ .../CharacterStringSerializer.java | 20 + .../serialization/EnumeratedDeserializer.java | 48 +++ .../serialization/EnumeratedSerializer.java | 53 +++ .../serialization/IntegerDeserializer.java | 47 +++ .../NestedSequenceOfDeserializer.java | 60 +++ .../NestedSequenceOfSerializer.java | 55 +++ .../serialization/OpenTypeDeserializer.java | 54 +++ .../serialization/OpenTypeSerializer.java | 76 ++++ .../ParameterizedTypeDeserializer.java | 68 ++++ .../SequenceOfEnumeratedDeserializer.java | 53 +++ .../serialization/SerializationUtil.java | 18 + .../plugin/serialization/package-info.java | 4 + .../jpo/ode/plugin/types/Asn1Bitstring.java | 113 ++++++ .../its/jpo/ode/plugin/types/Asn1Boolean.java | 55 +++ .../ode/plugin/types/Asn1CharacterString.java | 41 ++ .../its/jpo/ode/plugin/types/Asn1Choice.java | 58 +++ .../jpo/ode/plugin/types/Asn1Enumerated.java | 10 + .../its/jpo/ode/plugin/types/Asn1Field.java | 5 + .../its/jpo/ode/plugin/types/Asn1Integer.java | 68 ++++ .../jpo/ode/plugin/types/Asn1OctetString.java | 11 + .../jpo/ode/plugin/types/Asn1Sequence.java | 31 ++ .../jpo/ode/plugin/types/Asn1SequenceOf.java | 41 ++ .../its/jpo/ode/plugin/types/Asn1Type.java | 8 + .../its/jpo/ode/plugin/types/IA5String.java | 15 + .../its/jpo/ode/plugin/types/UnknownType.java | 9 + .../jpo/ode/plugin/types/package-info.java | 4 + .../its/jpo/ode/plugin/utils/BitUtils.java | 22 ++ .../ode/coder/OdeTimDataCreatorHelper.java | 11 +- 215 files changed, 10819 insertions(+), 20 deletions(-) create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/package-info.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Type.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/package-info.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java index ca1a469ac..5e0341fd9 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java @@ -104,6 +104,31 @@ public static ObjectNode createEmbeddedJsonArrayForXmlConversion(String childKey return childNode; } + public static String findXmlContentString(String xml, String tagName) { + // Construct the start and end tag strings + String startTag = "<" + tagName + ">"; + String endTag = ""; + + // Find the start index of the start tag + int startIndex = xml.indexOf(startTag); + if (startIndex == -1) { + // Tag not found + return null; + } + + // Find the end index of the end tag, after the start tag + int endIndex = xml.indexOf(endTag, startIndex); + if (endIndex == -1) { + // End tag not found + return null; + } + + // Add the length of the end tag to get the complete end index + endIndex += endTag.length(); + + return xml.substring(startIndex, endIndex); + } + public static String toXmlStatic(Object o) throws XmlUtilsException { String xml; try { diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java index 235c9c0c9..37cea2c0a 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java @@ -15,8 +15,8 @@ ******************************************************************************/ package us.dot.its.jpo.ode.model; -import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.TravelerInformation; public class OdeTimPayload extends OdeMsgPayload { @@ -31,7 +31,7 @@ public OdeTimPayload(OdeTravelerInformationMessage tim) { this.setData(tim); } - public OdeTimPayload(J2735Tim tim) { + public OdeTimPayload(TravelerInformation tim) { super(tim); this.setData(tim); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java new file mode 100644 index 000000000..0777c6dd2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java @@ -0,0 +1,65 @@ +package us.dot.its.jpo.ode.plugin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to specify how to deserialize an ASN1 parameterized type, which + * is represented by an abstract generic class in Java. Modeled after the JsonTypeInfo and + * JsonSubTypes annotations in Jackson, but adding the ability to specify that the + * id field is an integer, not restricted to being a string like in Jackson. + * @author Ivan Yourshaw + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Asn1ParameterizedTypes { + + /** + * @return Name of the property used to determine which type to deserialize + */ + String idProperty(); + + /** + * @return Type of the id property, which may be integer or string + */ + IdType idType(); + + /** + * @return Name of the value property containing the payload which can be various types + * depending on the generic type parameters. + */ + String valueProperty(); + + /** + * @return Array of value types mapped to ids. + */ + Type[] value(); + + enum IdType { + INTEGER, + STRING + } + + /** + * Annotation to specify the type corresponding to an id. + */ + @interface Type { + /** + * @return The id if it is an integer + */ + int intId() default -1; + + /** + * @return The id if it is a string + */ + String stringId() default ""; + + /** + * @return The specific class to deserialize to + */ + Class value(); + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java new file mode 100644 index 000000000..2b5f58954 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java @@ -0,0 +1,47 @@ +package us.dot.its.jpo.ode.plugin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Provides metadata for a property of an Asn.1 class: components of Asn1Sequence, or alternatives of Asn1Choice. + * @author Ivan Yourshaw + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface Asn1Property { + /** + * @return Tag number indicating the canonical order of serialization + */ + int tag(); + + /** + * @return Name of the original non-normalized property. Not required if the Java property name is the same as + * the ASN.1 name. + */ + String name() default ""; + + /** + * @return True if the property is an extension, false if part of the root + */ + boolean extension() default false; + + /** + * @return True if the ASN.1 OPTIONAL marker is present + */ + boolean optional() default false; + + /** + * @return Default value specified by the ASN.1 DEFAULT marker. String can be converted to an integer for int types. + */ + String defaultValue() default ""; + + /** + * @return Indicates that the property is an ASN1 Open Type, so UPER encoding needs to use a length determinant + * as described in T-REC-X.691 (2021/2) section 11.2. + */ + boolean openType() default false; + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java new file mode 100644 index 000000000..00f66faaa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java @@ -0,0 +1,4 @@ +/** + * Annotations needed for ASN.1 UPER encoding + */ +package us.dot.its.jpo.ode.plugin.annotations; \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java new file mode 100644 index 000000000..3971504a9 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DegreesLat extends Asn1Integer { + + public DegreesLat() { + super(-90L, 90L); + } + + @JsonCreator + public DegreesLat(long value) { + this(); + this.value = value; + } + + public static class DegreesLatDeserializer extends IntegerDeserializer { + public DegreesLatDeserializer() { + super(DegreesLat.class); + } + + @Override + protected DegreesLat construct() { + return new DegreesLat(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java new file mode 100644 index 000000000..dbfb480d2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DegreesLong extends Asn1Integer { + + public DegreesLong() { + super(-180L, 180L); + } + + @JsonCreator + public DegreesLong(long value) { + this(); + this.value = value; + } + + public static class DegreesLongDeserializer extends IntegerDeserializer { + public DegreesLongDeserializer() { + super(DegreesLong.class); + } + + @Override + protected DegreesLong construct() { + return new DegreesLong(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java new file mode 100644 index 000000000..98ba42c38 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Elevation extends Asn1Integer { + + public Elevation() { + super(-32768L, 32767L); + } + + @JsonCreator + public Elevation(long value) { + this(); + this.value = value; + } + + public static class ElevationDeserializer extends IntegerDeserializer { + public ElevationDeserializer() { + super(Elevation.class); + } + + @Override + protected Elevation construct() { + return new Elevation(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java new file mode 100644 index 000000000..ad02e6cf9 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class LaneDataAttribute_addGrpB extends Asn1Sequence { + + LaneDataAttribute_addGrpB() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java new file mode 100644 index 000000000..7485ccd38 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import com.fasterxml.jackson.annotation.JsonRootName; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonRootName("Reg_LaneDataAttribute") +public class LaneDataAttribute_addGrpBReg_LaneDataAttribute extends Reg_LaneDataAttribute { + + public LaneDataAttribute_addGrpBReg_LaneDataAttribute() { + super(2, "LaneDataAttribute_addGrpB"); + } + + @Override + @JsonSerialize(using = LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.class) + public LaneDataAttribute_addGrpB getRegExtValue() { + return super.getRegExtValue(); + } + + @Override + @JsonDeserialize(using = LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.class) + public void setRegExtValue(LaneDataAttribute_addGrpB value) { + super.setRegExtValue(value); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java new file mode 100644 index 000000000..528ea1d43 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer + extends + OpenTypeDeserializer { + + public LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer() { + super(LaneDataAttribute_addGrpB.class, "LaneDataAttribute_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java new file mode 100644 index 000000000..f33420c9e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer + extends + OpenTypeSerializer { + + public LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer() { + super(LaneDataAttribute_addGrpB.class, "regExtValue", "LaneDataAttribute_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java new file mode 100644 index 000000000..e1a7a2791 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LatitudeDMS extends Asn1Integer { + + public LatitudeDMS() { + super(-32400000L, 32400000L); + } + + @JsonCreator + public LatitudeDMS(long value) { + this(); + this.value = value; + } + + public static class LatitudeDMSDeserializer extends IntegerDeserializer { + public LatitudeDMSDeserializer() { + super(LatitudeDMS.class); + } + + @Override + protected LatitudeDMS construct() { + return new LatitudeDMS(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java new file mode 100644 index 000000000..3102137cb --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java @@ -0,0 +1,68 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class LatitudeDMS2 extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = DegreesLat.DegreesLatDeserializer.class) + private DegreesLat d; + @Asn1Property(tag = 1) + @JsonDeserialize(using = MinutesAngle.MinutesAngleDeserializer.class) + private MinutesAngle m; + @Asn1Property(tag = 2) + @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) + private SecondsAngle s; + + public DegreesLat getD() { + return d; + } + + public void setD(DegreesLat d) { + this.d = d; + } + + public MinutesAngle getM() { + return m; + } + + public void setM(MinutesAngle m) { + this.m = m; + } + + public SecondsAngle getS() { + return s; + } + + public void setS(SecondsAngle s) { + this.s = s; + } + + LatitudeDMS2() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java new file mode 100644 index 000000000..29d2c87b5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LongitudeDMS extends Asn1Integer { + + public LongitudeDMS() { + super(-64800000L, 64800000L); + } + + @JsonCreator + public LongitudeDMS(long value) { + this(); + this.value = value; + } + + public static class LongitudeDMSDeserializer extends IntegerDeserializer { + public LongitudeDMSDeserializer() { + super(LongitudeDMS.class); + } + + @Override + protected LongitudeDMS construct() { + return new LongitudeDMS(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java new file mode 100644 index 000000000..91d0b02f2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java @@ -0,0 +1,68 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class LongitudeDMS2 extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = DegreesLong.DegreesLongDeserializer.class) + private DegreesLong d; + @Asn1Property(tag = 1) + @JsonDeserialize(using = MinutesAngle.MinutesAngleDeserializer.class) + private MinutesAngle m; + @Asn1Property(tag = 2) + @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) + private SecondsAngle s; + + public DegreesLong getD() { + return d; + } + + public void setD(DegreesLong d) { + this.d = d; + } + + public MinutesAngle getM() { + return m; + } + + public void setM(MinutesAngle m) { + this.m = m; + } + + public SecondsAngle getS() { + return s; + } + + public void setS(SecondsAngle s) { + this.s = s; + } + + LongitudeDMS2() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java new file mode 100644 index 000000000..1a559c930 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MinutesAngle extends Asn1Integer { + + public MinutesAngle() { + super(0L, 59L); + } + + @JsonCreator + public MinutesAngle(long value) { + this(); + this.value = value; + } + + public static class MinutesAngleDeserializer extends IntegerDeserializer { + public MinutesAngleDeserializer() { + super(MinutesAngle.class); + } + + @Override + protected MinutesAngle construct() { + return new MinutesAngle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java new file mode 100644 index 000000000..fcbcbad4d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java @@ -0,0 +1,60 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeOffsetPointXY_addGrpB extends Asn1Choice { + + @Asn1Property(tag = 0) + private Node_LLdms_48b posA; + @Asn1Property(tag = 1) + private Node_LLdms_80b posB; + + NodeOffsetPointXY_addGrpB() { + super(true); + } + + public Node_LLdms_48b getPosA() { + return posA; + } + + public void setPosA(Node_LLdms_48b posA) { + this.posA = posA; + } + + public Node_LLdms_80b getPosB() { + return posB; + } + + public void setPosB(Node_LLdms_80b posB) { + this.posB = posB; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java new file mode 100644 index 000000000..7df4a3a50 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import com.fasterxml.jackson.annotation.JsonRootName; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointXY; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonRootName("Reg_NodeOffsetPointXY") +public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY extends Reg_NodeOffsetPointXY { + + public NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY() { + super(2, "NodeOffsetPointXY_addGrpB"); + } + + @Override + @JsonSerialize(using = NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.class) + public NodeOffsetPointXY_addGrpB getRegExtValue() { + return super.getRegExtValue(); + } + + @Override + @JsonDeserialize(using = NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.class) + public void setRegExtValue(NodeOffsetPointXY_addGrpB value) { + super.setRegExtValue(value); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java new file mode 100644 index 000000000..58a329960 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer + extends + OpenTypeDeserializer { + + public NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer() { + super(NodeOffsetPointXY_addGrpB.class, "NodeOffsetPointXY_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java new file mode 100644 index 000000000..5e37e5770 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer + extends + OpenTypeSerializer { + + public NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer() { + super(NodeOffsetPointXY_addGrpB.class, "regExtValue", "NodeOffsetPointXY_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java new file mode 100644 index 000000000..1ee2af7f2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LLdms_48b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = LongitudeDMS.LongitudeDMSDeserializer.class) + private LongitudeDMS lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = LatitudeDMS.LatitudeDMSDeserializer.class) + private LatitudeDMS lat; + + public LongitudeDMS getLon() { + return lon; + } + + public void setLon(LongitudeDMS lon) { + this.lon = lon; + } + + public LatitudeDMS getLat() { + return lat; + } + + public void setLat(LatitudeDMS lat) { + this.lat = lat; + } + + Node_LLdms_48b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java new file mode 100644 index 000000000..8547424b0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LLdms_80b extends Asn1Sequence { + + @Asn1Property(tag = 0) + private LongitudeDMS2 lon; + @Asn1Property(tag = 1) + private LatitudeDMS2 lat; + + public LongitudeDMS2 getLon() { + return lon; + } + + public void setLon(LongitudeDMS2 lon) { + this.lon = lon; + } + + public LatitudeDMS2 getLat() { + return lat; + } + + public void setLat(LatitudeDMS2 lat) { + this.lat = lat; + } + + Node_LLdms_80b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java new file mode 100644 index 000000000..95b97876b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java @@ -0,0 +1,66 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Position3D_addGrpB extends Asn1Sequence { + + @Asn1Property(tag = 0) + private LatitudeDMS2 latitude; + @Asn1Property(tag = 1) + private LongitudeDMS2 longitude; + @Asn1Property(tag = 2) + @JsonDeserialize(using = Elevation.ElevationDeserializer.class) + private Elevation elevation; + + public LatitudeDMS2 getLatitude() { + return latitude; + } + + public void setLatitude(LatitudeDMS2 latitude) { + this.latitude = latitude; + } + + public LongitudeDMS2 getLongitude() { + return longitude; + } + + public void setLongitude(LongitudeDMS2 longitude) { + this.longitude = longitude; + } + + public Elevation getElevation() { + return elevation; + } + + public void setElevation(Elevation elevation) { + this.elevation = elevation; + } + + Position3D_addGrpB() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java new file mode 100644 index 000000000..5b0f3bc27 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import com.fasterxml.jackson.annotation.JsonRootName; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonRootName("Reg_Position3D") +public class Position3D_addGrpBReg_Position3D extends Reg_Position3D { + + public Position3D_addGrpBReg_Position3D() { + super(2, "Position3D_addGrpB"); + } + + @Override + @JsonSerialize(using = Position3D_addGrpBReg_Position3DValueSerializer.class) + public Position3D_addGrpB getRegExtValue() { + return super.getRegExtValue(); + } + + @Override + @JsonDeserialize(using = Position3D_addGrpBReg_Position3DValueDeserializer.class) + public void setRegExtValue(Position3D_addGrpB value) { + super.setRegExtValue(value); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java new file mode 100644 index 000000000..84496f548 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Position3D_addGrpBReg_Position3DValueDeserializer extends OpenTypeDeserializer { + + public Position3D_addGrpBReg_Position3DValueDeserializer() { + super(Position3D_addGrpB.class, "Position3D_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java new file mode 100644 index 000000000..91fa1c891 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Position3D_addGrpBReg_Position3DValueSerializer extends OpenTypeSerializer { + + public Position3D_addGrpBReg_Position3DValueSerializer() { + super(Position3D_addGrpB.class, "regExtValue", "Position3D_addGrpB"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java new file mode 100644 index 000000000..b59a9329c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SecondsAngle extends Asn1Integer { + + public SecondsAngle() { + super(0L, 5999L); + } + + @JsonCreator + public SecondsAngle(long value) { + this(); + this.value = value; + } + + public static class SecondsAngleDeserializer extends IntegerDeserializer { + public SecondsAngleDeserializer() { + super(SecondsAngle.class); + } + + @Override + protected SecondsAngle construct() { + return new SecondsAngle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java new file mode 100644 index 000000000..c73c8af2b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java @@ -0,0 +1,56 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Altitude extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = AltitudeValue.AltitudeValueDeserializer.class) + private AltitudeValue value; + @Asn1Property(tag = 1) + private AltitudeConfidence confidence; + + public AltitudeValue getValue() { + return value; + } + + public void setValue(AltitudeValue value) { + this.value = value; + } + + public AltitudeConfidence getConfidence() { + return confidence; + } + + public void setConfidence(AltitudeConfidence confidence) { + this.confidence = confidence; + } + + Altitude() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java new file mode 100644 index 000000000..8c9bb01e5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = AltitudeConfidenceSerializer.class) +@JsonDeserialize(using = AltitudeConfidenceDeserializer.class) +public enum AltitudeConfidence implements Asn1Enumerated { + alt_000_01(0, "alt-000-01"), alt_000_02(1, "alt-000-02"), alt_000_05(2, "alt-000-05"), alt_000_10(3, + "alt-000-10"), alt_000_20(4, "alt-000-20"), alt_000_50(5, "alt-000-50"), alt_001_00(6, + "alt-001-00"), alt_002_00(7, "alt-002-00"), alt_005_00(8, "alt-005-00"), alt_010_00(9, + "alt-010-00"), alt_020_00(10, "alt-020-00"), alt_050_00(11, "alt-050-00"), alt_100_00(12, + "alt-100-00"), alt_200_00(13, + "alt-200-00"), outOfRange(14, "outOfRange"), unavailable(15, "unavailable"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private AltitudeConfidence(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 15; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java new file mode 100644 index 000000000..39232d747 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class AltitudeConfidenceDeserializer extends EnumeratedDeserializer { + + AltitudeConfidenceDeserializer() { + super(AltitudeConfidence.class); + } + + @Override + protected AltitudeConfidence[] listEnumValues() { + return AltitudeConfidence.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java new file mode 100644 index 000000000..1f1722c19 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class AltitudeConfidenceSerializer extends EnumeratedSerializer { + + AltitudeConfidenceSerializer() { + super(AltitudeConfidence.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java new file mode 100644 index 000000000..77a6295c1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class AltitudeValue extends Asn1Integer { + + public AltitudeValue() { + super(-100000L, 800001L); + } + + @JsonCreator + public AltitudeValue(long value) { + this(); + this.value = value; + } + + public static class AltitudeValueDeserializer extends IntegerDeserializer { + public AltitudeValueDeserializer() { + super(AltitudeValue.class); + } + + @Override + protected AltitudeValue construct() { + return new AltitudeValue(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java new file mode 100644 index 000000000..3d01b1604 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java @@ -0,0 +1,44 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Position3D_addGrpC extends Asn1Sequence { + + @Asn1Property(tag = 0) + private Altitude altitude; + + public Altitude getAltitude() { + return altitude; + } + + public void setAltitude(Altitude altitude) { + this.altitude = altitude; + } + + Position3D_addGrpC() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java new file mode 100644 index 000000000..8dd2054ca --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import com.fasterxml.jackson.annotation.JsonRootName; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonRootName("Reg_Position3D") +public class Position3D_addGrpCReg_Position3D extends Reg_Position3D { + + public Position3D_addGrpCReg_Position3D() { + super(3, "Position3D_addGrpC"); + } + + @Override + @JsonSerialize(using = Position3D_addGrpCReg_Position3DValueSerializer.class) + public Position3D_addGrpC getRegExtValue() { + return super.getRegExtValue(); + } + + @Override + @JsonDeserialize(using = Position3D_addGrpCReg_Position3DValueDeserializer.class) + public void setRegExtValue(Position3D_addGrpC value) { + super.setRegExtValue(value); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java new file mode 100644 index 000000000..9d9d8995c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Position3D_addGrpCReg_Position3DValueDeserializer extends OpenTypeDeserializer { + + public Position3D_addGrpCReg_Position3DValueDeserializer() { + super(Position3D_addGrpC.class, "Position3D_addGrpC"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java new file mode 100644 index 000000000..0345169aa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Position3D_addGrpCReg_Position3DValueSerializer extends OpenTypeSerializer { + + public Position3D_addGrpCReg_Position3DValueSerializer() { + super(Position3D_addGrpC.class, "regExtValue", "Position3D_addGrpC"); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java new file mode 100644 index 000000000..747b3c136 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Angle extends Asn1Integer { + + public Angle() { + super(0L, 28800L); + } + + @JsonCreator + public Angle(long value) { + this(); + this.value = value; + } + + public static class AngleDeserializer extends IntegerDeserializer { + public AngleDeserializer() { + super(Angle.class); + } + + @Override + protected Angle construct() { + return new Angle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java new file mode 100644 index 000000000..e90e05107 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java @@ -0,0 +1,66 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Circle extends Asn1Sequence { + + @Asn1Property(tag = 0) + private Position3D center; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Radius_B12.Radius_B12Deserializer.class) + private Radius_B12 radius; + @Asn1Property(tag = 2) + private DistanceUnits units; + + public Position3D getCenter() { + return center; + } + + public void setCenter(Position3D center) { + this.center = center; + } + + public Radius_B12 getRadius() { + return radius; + } + + public void setRadius(Radius_B12 radius) { + this.radius = radius; + } + + public DistanceUnits getUnits() { + return units; + } + + public void setUnits(DistanceUnits units) { + this.units = units; + } + + Circle() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java new file mode 100644 index 000000000..fa9decec4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java @@ -0,0 +1,192 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_ComputedLane; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ComputedLane extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = LaneID.LaneIDDeserializer.class) + private LaneID referenceLaneId; + @Asn1Property(tag = 1) + private OffsetXaxisChoice offsetXaxis; + @Asn1Property(tag = 2) + private OffsetYaxisChoice offsetYaxis; + @Asn1Property(tag = 3, optional = true) + @JsonDeserialize(using = Angle.AngleDeserializer.class) + private Angle rotateXY; + @Asn1Property(tag = 4, optional = true) + @JsonDeserialize(using = Scale_B12.Scale_B12Deserializer.class) + private Scale_B12 scaleXaxis; + @Asn1Property(tag = 5, optional = true) + @JsonDeserialize(using = Scale_B12.Scale_B12Deserializer.class) + private Scale_B12 scaleYaxis; + @Asn1Property(tag = 6, optional = true) + private SequenceOfRegional regional; + + public LaneID getReferenceLaneId() { + return referenceLaneId; + } + + public void setReferenceLaneId(LaneID referenceLaneId) { + this.referenceLaneId = referenceLaneId; + } + + @JsonInclude(Include.NON_NULL) + public static class OffsetXaxisChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = DrivenLineOffsetSm.DrivenLineOffsetSmDeserializer.class) + private DrivenLineOffsetSm small; + @Asn1Property(tag = 1) + @JsonDeserialize(using = DrivenLineOffsetLg.DrivenLineOffsetLgDeserializer.class) + private DrivenLineOffsetLg large; + + OffsetXaxisChoice() { + super(false); + } + + public DrivenLineOffsetSm getSmall() { + return small; + } + + public void setSmall(DrivenLineOffsetSm small) { + this.small = small; + } + + public DrivenLineOffsetLg getLarge() { + return large; + } + + public void setLarge(DrivenLineOffsetLg large) { + this.large = large; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public OffsetXaxisChoice getOffsetXaxis() { + return offsetXaxis; + } + + public void setOffsetXaxis(OffsetXaxisChoice offsetXaxis) { + this.offsetXaxis = offsetXaxis; + } + + @JsonInclude(Include.NON_NULL) + public static class OffsetYaxisChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = DrivenLineOffsetSm.DrivenLineOffsetSmDeserializer.class) + private DrivenLineOffsetSm small; + @Asn1Property(tag = 1) + @JsonDeserialize(using = DrivenLineOffsetLg.DrivenLineOffsetLgDeserializer.class) + private DrivenLineOffsetLg large; + + OffsetYaxisChoice() { + super(false); + } + + public DrivenLineOffsetSm getSmall() { + return small; + } + + public void setSmall(DrivenLineOffsetSm small) { + this.small = small; + } + + public DrivenLineOffsetLg getLarge() { + return large; + } + + public void setLarge(DrivenLineOffsetLg large) { + this.large = large; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public OffsetYaxisChoice getOffsetYaxis() { + return offsetYaxis; + } + + public void setOffsetYaxis(OffsetYaxisChoice offsetYaxis) { + this.offsetYaxis = offsetYaxis; + } + + public Angle getRotateXY() { + return rotateXY; + } + + public void setRotateXY(Angle rotateXY) { + this.rotateXY = rotateXY; + } + + public Scale_B12 getScaleXaxis() { + return scaleXaxis; + } + + public void setScaleXaxis(Scale_B12 scaleXaxis) { + this.scaleXaxis = scaleXaxis; + } + + public Scale_B12 getScaleYaxis() { + return scaleYaxis; + } + + public void setScaleYaxis(Scale_B12 scaleYaxis) { + this.scaleYaxis = scaleYaxis; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_ComputedLane.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + ComputedLane() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java new file mode 100644 index 000000000..f5194d6d0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DYear extends Asn1Integer { + + public DYear() { + super(0L, 4095L); + } + + @JsonCreator + public DYear(long value) { + this(); + this.value = value; + } + + public static class DYearDeserializer extends IntegerDeserializer { + public DYearDeserializer() { + super(DYear.class); + } + + @Override + protected DYear construct() { + return new DYear(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java new file mode 100644 index 000000000..ad7b4d24d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DeltaAngle extends Asn1Integer { + + public DeltaAngle() { + super(-150L, 150L); + } + + @JsonCreator + public DeltaAngle(long value) { + this(); + this.value = value; + } + + public static class DeltaAngleDeserializer extends IntegerDeserializer { + public DeltaAngleDeserializer() { + super(DeltaAngle.class); + } + + @Override + protected DeltaAngle construct() { + return new DeltaAngle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java new file mode 100644 index 000000000..3816bb79f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java @@ -0,0 +1,34 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.IA5String; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DescriptiveName extends IA5String { + + public DescriptiveName() { + super(1, 63); + } + + @JsonCreator + public DescriptiveName(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java new file mode 100644 index 000000000..87d53e48d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java @@ -0,0 +1,52 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = DirectionOfUseSerializer.class) +@JsonDeserialize(using = DirectionOfUseDeserializer.class) +public enum DirectionOfUse implements Asn1Enumerated { + unavailable(0, "unavailable"), forward(1, "forward"), reverse(2, "reverse"), both(3, "both"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private DirectionOfUse(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 3; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java new file mode 100644 index 000000000..22e4c7c3d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DirectionOfUseDeserializer extends EnumeratedDeserializer { + + DirectionOfUseDeserializer() { + super(DirectionOfUse.class); + } + + @Override + protected DirectionOfUse[] listEnumValues() { + return DirectionOfUse.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java new file mode 100644 index 000000000..ddf1dde5b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DirectionOfUseSerializer extends EnumeratedSerializer { + + DirectionOfUseSerializer() { + super(DirectionOfUse.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java new file mode 100644 index 000000000..07ab86509 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = DistanceUnitsSerializer.class) +@JsonDeserialize(using = DistanceUnitsDeserializer.class) +public enum DistanceUnits implements Asn1Enumerated { + centimeter(0, "centimeter"), cm2_5(1, "cm2-5"), decimeter(2, "decimeter"), meter(3, "meter"), kilometer(4, + "kilometer"), foot(5, "foot"), yard(6, "yard"), mile(7, "mile"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private DistanceUnits(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 7; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java new file mode 100644 index 000000000..75b2923fa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DistanceUnitsDeserializer extends EnumeratedDeserializer { + + DistanceUnitsDeserializer() { + super(DistanceUnits.class); + } + + @Override + protected DistanceUnits[] listEnumValues() { + return DistanceUnits.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java new file mode 100644 index 000000000..e9cd7bad2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DistanceUnitsSerializer extends EnumeratedSerializer { + + DistanceUnitsSerializer() { + super(DistanceUnits.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java new file mode 100644 index 000000000..0f8447119 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DrivenLineOffsetLg extends Asn1Integer { + + public DrivenLineOffsetLg() { + super(-32767L, 32767L); + } + + @JsonCreator + public DrivenLineOffsetLg(long value) { + this(); + this.value = value; + } + + public static class DrivenLineOffsetLgDeserializer extends IntegerDeserializer { + public DrivenLineOffsetLgDeserializer() { + super(DrivenLineOffsetLg.class); + } + + @Override + protected DrivenLineOffsetLg construct() { + return new DrivenLineOffsetLg(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java new file mode 100644 index 000000000..ff8e342c0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class DrivenLineOffsetSm extends Asn1Integer { + + public DrivenLineOffsetSm() { + super(-2047L, 2047L); + } + + @JsonCreator + public DrivenLineOffsetSm(long value) { + this(); + this.value = value; + } + + public static class DrivenLineOffsetSmDeserializer extends IntegerDeserializer { + public DrivenLineOffsetSmDeserializer() { + super(DrivenLineOffsetSm.class); + } + + @Override + protected DrivenLineOffsetSm construct() { + return new DrivenLineOffsetSm(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java new file mode 100644 index 000000000..64d9b20f3 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Elevation extends Asn1Integer { + + public Elevation() { + super(-4096L, 61439L); + } + + @JsonCreator + public Elevation(long value) { + this(); + this.value = value; + } + + public static class ElevationDeserializer extends IntegerDeserializer { + public ElevationDeserializer() { + super(Elevation.class); + } + + @Override + protected Elevation construct() { + return new Elevation(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java new file mode 100644 index 000000000..99e2e3637 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class ExitService extends Asn1SequenceOf { + + ExitService() { + super(ExitServiceSequence.class, 1L, 16L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java new file mode 100644 index 000000000..0c2987237 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java @@ -0,0 +1,84 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ExitServiceSequence extends Asn1Sequence { + + @Asn1Property(tag = 0) + private ItemChoice item; + + @JsonInclude(Include.NON_NULL) + public static class ItemChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + private ITIScodes itis; + @Asn1Property(tag = 1) + private ITIStextPhrase text; + + ItemChoice() { + super(false); + } + + public ITIScodes getItis() { + return itis; + } + + public void setItis(ITIScodes itis) { + this.itis = itis; + } + + public ITIStextPhrase getText() { + return text; + } + + public void setText(ITIStextPhrase text) { + this.text = text; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ItemChoice getItem() { + return item; + } + + public void setItem(ItemChoice item) { + this.item = item; + } + + ExitServiceSequence() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java new file mode 100644 index 000000000..2c57b326a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java @@ -0,0 +1,62 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = ExtentSerializer.class) +@JsonDeserialize(using = ExtentDeserializer.class) +public enum Extent implements Asn1Enumerated { + useInstantlyOnly(0, "useInstantlyOnly"), useFor3meters(1, "useFor3meters"), useFor10meters(2, + "useFor10meters"), useFor50meters(3, "useFor50meters"), useFor100meters(4, + "useFor100meters"), useFor500meters(5, "useFor500meters"), useFor1000meters(6, + "useFor1000meters"), useFor5000meters(7, "useFor5000meters"), useFor10000meters(8, + "useFor10000meters"), useFor50000meters(9, "useFor50000meters"), useFor100000meters( + 10, "useFor100000meters"), useFor500000meters(11, + "useFor500000meters"), useFor1000000meters(12, + "useFor1000000meters"), useFor5000000meters(13, + "useFor5000000meters"), useFor10000000meters(14, + "useFor10000000meters"), forever(15, + "forever"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private Extent(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 15; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java new file mode 100644 index 000000000..dd18b82e4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class ExtentDeserializer extends EnumeratedDeserializer { + + ExtentDeserializer() { + super(Extent.class); + } + + @Override + protected Extent[] listEnumValues() { + return Extent.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java new file mode 100644 index 000000000..955baaf1f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class ExtentSerializer extends EnumeratedSerializer { + + ExtentSerializer() { + super(Extent.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java new file mode 100644 index 000000000..f9c733971 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class FurtherInfoID extends Asn1OctetString { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + + public FurtherInfoID() { + super(2, 2); + } + + @JsonCreator + public FurtherInfoID(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java new file mode 100644 index 000000000..bc5b22371 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class GenericSignage extends Asn1SequenceOf { + + GenericSignage() { + super(GenericSignageSequence.class, 1L, 16L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java new file mode 100644 index 000000000..4dda92563 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java @@ -0,0 +1,84 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class GenericSignageSequence extends Asn1Sequence { + + @Asn1Property(tag = 0) + private ItemChoice item; + + @JsonInclude(Include.NON_NULL) + public static class ItemChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + private ITIScodes itis; + @Asn1Property(tag = 1) + private ITIStextPhrase text; + + ItemChoice() { + super(false); + } + + public ITIScodes getItis() { + return itis; + } + + public void setItis(ITIScodes itis) { + this.itis = itis; + } + + public ITIStextPhrase getText() { + return text; + } + + public void setText(ITIStextPhrase text) { + this.text = text; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ItemChoice getItem() { + return item; + } + + public void setItem(ItemChoice item) { + this.item = item; + } + + GenericSignageSequence() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java new file mode 100644 index 000000000..8cbee9e51 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java @@ -0,0 +1,183 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeographicalPath; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeographicalPath extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + private DescriptiveName name; + @Asn1Property(tag = 1, optional = true) + private RoadSegmentReferenceID id; + @Asn1Property(tag = 2, optional = true) + private Position3D anchor; + @Asn1Property(tag = 3, optional = true) + @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + private LaneWidth laneWidth; + @Asn1Property(tag = 4, optional = true) + private DirectionOfUse directionality; + @Asn1Property(tag = 5, optional = true) + private Asn1Boolean closedPath; + @Asn1Property(tag = 6, optional = true) + private HeadingSlice direction; + @Asn1Property(tag = 7, optional = true) + private DescriptionChoice description; + @Asn1Property(tag = 8, optional = true) + private SequenceOfRegional regional; + + public DescriptiveName getName() { + return name; + } + + public void setName(DescriptiveName name) { + this.name = name; + } + + public RoadSegmentReferenceID getId() { + return id; + } + + public void setId(RoadSegmentReferenceID id) { + this.id = id; + } + + public Position3D getAnchor() { + return anchor; + } + + public void setAnchor(Position3D anchor) { + this.anchor = anchor; + } + + public LaneWidth getLaneWidth() { + return laneWidth; + } + + public void setLaneWidth(LaneWidth laneWidth) { + this.laneWidth = laneWidth; + } + + public DirectionOfUse getDirectionality() { + return directionality; + } + + public void setDirectionality(DirectionOfUse directionality) { + this.directionality = directionality; + } + + public Asn1Boolean getClosedPath() { + return closedPath; + } + + public void setClosedPath(Asn1Boolean closedPath) { + this.closedPath = closedPath; + } + + public HeadingSlice getDirection() { + return direction; + } + + public void setDirection(HeadingSlice direction) { + this.direction = direction; + } + + @JsonInclude(Include.NON_NULL) + public static class DescriptionChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private OffsetSystem path; + @Asn1Property(tag = 1) + private GeometricProjection geometry; + @Asn1Property(tag = 2) + private ValidRegion oldRegion; + + DescriptionChoice() { + super(true); + } + + public OffsetSystem getPath() { + return path; + } + + public void setPath(OffsetSystem path) { + this.path = path; + } + + public GeometricProjection getGeometry() { + return geometry; + } + + public void setGeometry(GeometricProjection geometry) { + this.geometry = geometry; + } + + public ValidRegion getOldRegion() { + return oldRegion; + } + + public void setOldRegion(ValidRegion oldRegion) { + this.oldRegion = oldRegion; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public DescriptionChoice getDescription() { + return description; + } + + public void setDescription(DescriptionChoice description) { + this.description = description; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeographicalPath.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + GeographicalPath() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java new file mode 100644 index 000000000..63805fcda --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java @@ -0,0 +1,95 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeometricProjection; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class GeometricProjection extends Asn1Sequence { + + @Asn1Property(tag = 0) + private HeadingSlice direction; + @Asn1Property(tag = 1, optional = true) + private Extent extent; + @Asn1Property(tag = 2, optional = true) + @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + private LaneWidth laneWidth; + @Asn1Property(tag = 3) + private Circle circle; + @Asn1Property(tag = 4, optional = true) + private SequenceOfRegional regional; + + public HeadingSlice getDirection() { + return direction; + } + + public void setDirection(HeadingSlice direction) { + this.direction = direction; + } + + public Extent getExtent() { + return extent; + } + + public void setExtent(Extent extent) { + this.extent = extent; + } + + public LaneWidth getLaneWidth() { + return laneWidth; + } + + public void setLaneWidth(LaneWidth laneWidth) { + this.laneWidth = laneWidth; + } + + public Circle getCircle() { + return circle; + } + + public void setCircle(Circle circle) { + this.circle = circle; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeometricProjection.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + GeometricProjection() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java new file mode 100644 index 000000000..bc4993ac9 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java @@ -0,0 +1,163 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonDeserialize(using = HeadingSliceDeserializer.class) +public class HeadingSlice extends Asn1Bitstring { + + public boolean isFrom000_0to022_5degrees() { + return get(0); + } + + public void setFrom000_0to022_5degrees(boolean from000_0to022_5degrees) { + set(0, from000_0to022_5degrees); + } + + public boolean isFrom022_5to045_0degrees() { + return get(1); + } + + public void setFrom022_5to045_0degrees(boolean from022_5to045_0degrees) { + set(1, from022_5to045_0degrees); + } + + public boolean isFrom045_0to067_5degrees() { + return get(2); + } + + public void setFrom045_0to067_5degrees(boolean from045_0to067_5degrees) { + set(2, from045_0to067_5degrees); + } + + public boolean isFrom067_5to090_0degrees() { + return get(3); + } + + public void setFrom067_5to090_0degrees(boolean from067_5to090_0degrees) { + set(3, from067_5to090_0degrees); + } + + public boolean isFrom090_0to112_5degrees() { + return get(4); + } + + public void setFrom090_0to112_5degrees(boolean from090_0to112_5degrees) { + set(4, from090_0to112_5degrees); + } + + public boolean isFrom112_5to135_0degrees() { + return get(5); + } + + public void setFrom112_5to135_0degrees(boolean from112_5to135_0degrees) { + set(5, from112_5to135_0degrees); + } + + public boolean isFrom135_0to157_5degrees() { + return get(6); + } + + public void setFrom135_0to157_5degrees(boolean from135_0to157_5degrees) { + set(6, from135_0to157_5degrees); + } + + public boolean isFrom157_5to180_0degrees() { + return get(7); + } + + public void setFrom157_5to180_0degrees(boolean from157_5to180_0degrees) { + set(7, from157_5to180_0degrees); + } + + public boolean isFrom180_0to202_5degrees() { + return get(8); + } + + public void setFrom180_0to202_5degrees(boolean from180_0to202_5degrees) { + set(8, from180_0to202_5degrees); + } + + public boolean isFrom202_5to225_0degrees() { + return get(9); + } + + public void setFrom202_5to225_0degrees(boolean from202_5to225_0degrees) { + set(9, from202_5to225_0degrees); + } + + public boolean isFrom225_0to247_5degrees() { + return get(10); + } + + public void setFrom225_0to247_5degrees(boolean from225_0to247_5degrees) { + set(10, from225_0to247_5degrees); + } + + public boolean isFrom247_5to270_0degrees() { + return get(11); + } + + public void setFrom247_5to270_0degrees(boolean from247_5to270_0degrees) { + set(11, from247_5to270_0degrees); + } + + public boolean isFrom270_0to292_5degrees() { + return get(12); + } + + public void setFrom270_0to292_5degrees(boolean from270_0to292_5degrees) { + set(12, from270_0to292_5degrees); + } + + public boolean isFrom292_5to315_0degrees() { + return get(13); + } + + public void setFrom292_5to315_0degrees(boolean from292_5to315_0degrees) { + set(13, from292_5to315_0degrees); + } + + public boolean isFrom315_0to337_5degrees() { + return get(14); + } + + public void setFrom315_0to337_5degrees(boolean from315_0to337_5degrees) { + set(14, from315_0to337_5degrees); + } + + public boolean isFrom337_5to360_0degrees() { + return get(15); + } + + public void setFrom337_5to360_0degrees(boolean from337_5to360_0degrees) { + set(15, from337_5to360_0degrees); + } + + public HeadingSlice() { + super(16, false, + new String[]{"from000-0to022-5degrees", "from022-5to045-0degrees", "from045-0to067-5degrees", + "from067-5to090-0degrees", "from090-0to112-5degrees", "from112-5to135-0degrees", + "from135-0to157-5degrees", "from157-5to180-0degrees", "from180-0to202-5degrees", + "from202-5to225-0degrees", "from225-0to247-5degrees", "from247-5to270-0degrees", + "from270-0to292-5degrees", "from292-5to315-0degrees", "from315-0to337-5degrees", + "from337-5to360-0degrees"}); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java new file mode 100644 index 000000000..f34c946c5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.BitStringDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class HeadingSliceDeserializer extends BitStringDeserializer { + + HeadingSliceDeserializer() { + super(HeadingSlice.class); + } + + @Override + protected HeadingSlice construct() { + return new HeadingSlice(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java new file mode 100644 index 000000000..ffff1a3a1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java @@ -0,0 +1,34 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.IA5String; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class ITIStextPhrase extends IA5String { + + public ITIStextPhrase() { + super(1, 16); + } + + @JsonCreator + public ITIStextPhrase(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java new file mode 100644 index 000000000..72f01b53e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java @@ -0,0 +1,129 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class LaneDataAttribute extends Asn1Choice { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = DeltaAngle.DeltaAngleDeserializer.class) + private DeltaAngle pathEndPointAngle; + @Asn1Property(tag = 1) + @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + private RoadwayCrownAngle laneCrownPointCenter; + @Asn1Property(tag = 2) + @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + private RoadwayCrownAngle laneCrownPointLeft; + @Asn1Property(tag = 3) + @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + private RoadwayCrownAngle laneCrownPointRight; + @Asn1Property(tag = 4) + @JsonDeserialize(using = MergeDivergeNodeAngle.MergeDivergeNodeAngleDeserializer.class) + private MergeDivergeNodeAngle laneAngle; + @Asn1Property(tag = 5) + @JacksonXmlElementWrapper(localName = "speedLimits") + @JacksonXmlProperty(localName = "RegulatorySpeedLimit") + private SpeedLimitList speedLimits; + @Asn1Property(tag = 6) + private SequenceOfRegional regional; + + LaneDataAttribute() { + super(true); + } + + public DeltaAngle getPathEndPointAngle() { + return pathEndPointAngle; + } + + public void setPathEndPointAngle(DeltaAngle pathEndPointAngle) { + this.pathEndPointAngle = pathEndPointAngle; + } + + public RoadwayCrownAngle getLaneCrownPointCenter() { + return laneCrownPointCenter; + } + + public void setLaneCrownPointCenter(RoadwayCrownAngle laneCrownPointCenter) { + this.laneCrownPointCenter = laneCrownPointCenter; + } + + public RoadwayCrownAngle getLaneCrownPointLeft() { + return laneCrownPointLeft; + } + + public void setLaneCrownPointLeft(RoadwayCrownAngle laneCrownPointLeft) { + this.laneCrownPointLeft = laneCrownPointLeft; + } + + public RoadwayCrownAngle getLaneCrownPointRight() { + return laneCrownPointRight; + } + + public void setLaneCrownPointRight(RoadwayCrownAngle laneCrownPointRight) { + this.laneCrownPointRight = laneCrownPointRight; + } + + public MergeDivergeNodeAngle getLaneAngle() { + return laneAngle; + } + + public void setLaneAngle(MergeDivergeNodeAngle laneAngle) { + this.laneAngle = laneAngle; + } + + public SpeedLimitList getSpeedLimits() { + return speedLimits; + } + + public void setSpeedLimits(SpeedLimitList speedLimits) { + this.speedLimits = speedLimits; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java new file mode 100644 index 000000000..b9511ad3c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class LaneDataAttributeList extends Asn1SequenceOf { + + LaneDataAttributeList() { + super(LaneDataAttribute.class, 1L, 8L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java new file mode 100644 index 000000000..fe1570546 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LaneID extends Asn1Integer { + + public LaneID() { + super(0L, 255L); + } + + @JsonCreator + public LaneID(long value) { + this(); + this.value = value; + } + + public static class LaneIDDeserializer extends IntegerDeserializer { + public LaneIDDeserializer() { + super(LaneID.class); + } + + @Override + protected LaneID construct() { + return new LaneID(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java new file mode 100644 index 000000000..ea4f92b16 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class LaneWidth extends Asn1Integer { + + public LaneWidth() { + super(0L, 32767L); + } + + @JsonCreator + public LaneWidth(long value) { + this(); + this.value = value; + } + + public static class LaneWidthDeserializer extends IntegerDeserializer { + public LaneWidthDeserializer() { + super(LaneWidth.class); + } + + @Override + protected LaneWidth construct() { + return new LaneWidth(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java new file mode 100644 index 000000000..412c4005c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Latitude extends Asn1Integer { + + public Latitude() { + super(-900000000L, 900000001L); + } + + @JsonCreator + public Latitude(long value) { + this(); + this.value = value; + } + + public static class LatitudeDeserializer extends IntegerDeserializer { + public LatitudeDeserializer() { + super(Latitude.class); + } + + @Override + protected Latitude construct() { + return new Latitude(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java new file mode 100644 index 000000000..a0edc9d62 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Longitude extends Asn1Integer { + + public Longitude() { + super(-1799999999L, 1800000001L); + } + + @JsonCreator + public Longitude(long value) { + this(); + this.value = value; + } + + public static class LongitudeDeserializer extends IntegerDeserializer { + public LongitudeDeserializer() { + super(Longitude.class); + } + + @Override + protected Longitude construct() { + return new Longitude(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java new file mode 100644 index 000000000..6fcac726b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = MUTCDCodeSerializer.class) +@JsonDeserialize(using = MUTCDCodeDeserializer.class) +public enum MUTCDCode implements Asn1Enumerated { + none(0, "none"), regulatory(1, "regulatory"), warning(2, "warning"), maintenance(3, + "maintenance"), motoristService(4, "motoristService"), guide(5, "guide"), rec(6, "rec"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private MUTCDCode(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 6; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java new file mode 100644 index 000000000..0ab54e0aa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MUTCDCodeDeserializer extends EnumeratedDeserializer { + + MUTCDCodeDeserializer() { + super(MUTCDCode.class); + } + + @Override + protected MUTCDCode[] listEnumValues() { + return MUTCDCode.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java new file mode 100644 index 000000000..25d9dc376 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MUTCDCodeSerializer extends EnumeratedSerializer { + + MUTCDCodeSerializer() { + super(MUTCDCode.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java new file mode 100644 index 000000000..3f3f60175 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MergeDivergeNodeAngle extends Asn1Integer { + + public MergeDivergeNodeAngle() { + super(-180L, 180L); + } + + @JsonCreator + public MergeDivergeNodeAngle(long value) { + this(); + this.value = value; + } + + public static class MergeDivergeNodeAngleDeserializer extends IntegerDeserializer { + public MergeDivergeNodeAngleDeserializer() { + super(MergeDivergeNodeAngle.class); + } + + @Override + protected MergeDivergeNodeAngle construct() { + return new MergeDivergeNodeAngle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java new file mode 100644 index 000000000..acad5bdda --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MinuteOfTheYear extends Asn1Integer { + + public MinuteOfTheYear() { + super(0L, 527040L); + } + + @JsonCreator + public MinuteOfTheYear(long value) { + this(); + this.value = value; + } + + public static class MinuteOfTheYearDeserializer extends IntegerDeserializer { + public MinuteOfTheYearDeserializer() { + super(MinuteOfTheYear.class); + } + + @Override + protected MinuteOfTheYear construct() { + return new MinuteOfTheYear(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java new file mode 100644 index 000000000..5a09cc75c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MinutesDuration extends Asn1Integer { + + public MinutesDuration() { + super(0L, 32000L); + } + + @JsonCreator + public MinutesDuration(long value) { + this(); + this.value = value; + } + + public static class MinutesDurationDeserializer extends IntegerDeserializer { + public MinutesDurationDeserializer() { + super(MinutesDuration.class); + } + + @Override + protected MinutesDuration construct() { + return new MinutesDuration(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java new file mode 100644 index 000000000..292d0400e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MsgCRC extends Asn1OctetString { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + + public MsgCRC() { + super(2, 2); + } + + @JsonCreator + public MsgCRC(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java new file mode 100644 index 000000000..d10c6c481 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class MsgCount extends Asn1Integer { + + public MsgCount() { + super(0L, 127L); + } + + @JsonCreator + public MsgCount(long value) { + this(); + this.value = value; + } + + public static class MsgCountDeserializer extends IntegerDeserializer { + public MsgCountDeserializer() { + super(MsgCount.class); + } + + @Override + protected MsgCount construct() { + return new MsgCount(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java new file mode 100644 index 000000000..88cc1d2b1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java @@ -0,0 +1,56 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = NodeAttributeLLSerializer.class) +@JsonDeserialize(using = NodeAttributeLLDeserializer.class) +public enum NodeAttributeLL implements Asn1Enumerated { + reserved(0, "reserved"), stopLine(1, "stopLine"), roundedCapStyleA(2, "roundedCapStyleA"), roundedCapStyleB(3, + "roundedCapStyleB"), mergePoint(4, "mergePoint"), divergePoint(5, "divergePoint"), downstreamStopLine(6, + "downstreamStopLine"), downstreamStartNode(7, "downstreamStartNode"), closedToTraffic(8, + "closedToTraffic"), safeIsland(9, "safeIsland"), curbPresentAtStepOff(10, + "curbPresentAtStepOff"), hydrantPresent(11, "hydrantPresent"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private NodeAttributeLL(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 11; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java new file mode 100644 index 000000000..f1a7211b2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeAttributeLLDeserializer extends EnumeratedDeserializer { + + NodeAttributeLLDeserializer() { + super(NodeAttributeLL.class); + } + + @Override + protected NodeAttributeLL[] listEnumValues() { + return NodeAttributeLL.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java new file mode 100644 index 000000000..6fc8d6a7e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeAttributeLLList extends Asn1SequenceOf { + + NodeAttributeLLList() { + super(NodeAttributeLL.class, 1L, 8L); + } + + public static class NodeAttributeLLListDeserializer + extends + SequenceOfEnumeratedDeserializer { + public NodeAttributeLLListDeserializer() { + super(NodeAttributeLLList.class, NodeAttributeLL.class); + } + + @Override + protected NodeAttributeLL[] listEnumValues() { + return NodeAttributeLL.values(); + } + + @Override + protected NodeAttributeLLList construct() { + return new NodeAttributeLLList(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java new file mode 100644 index 000000000..c1248cb00 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeAttributeLLSerializer extends EnumeratedSerializer { + + NodeAttributeLLSerializer() { + super(NodeAttributeLL.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java new file mode 100644 index 000000000..1225b6c2b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java @@ -0,0 +1,121 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetLL; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class NodeAttributeSetLL extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + @JsonDeserialize(using = NodeAttributeLLList.NodeAttributeLLListDeserializer.class) + private NodeAttributeLLList localNode; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = SegmentAttributeLLList.SegmentAttributeLLListDeserializer.class) + private SegmentAttributeLLList disabled; + @Asn1Property(tag = 2, optional = true) + @JsonDeserialize(using = SegmentAttributeLLList.SegmentAttributeLLListDeserializer.class) + private SegmentAttributeLLList enabled; + @Asn1Property(tag = 3, optional = true) + @JacksonXmlElementWrapper(useWrapping = false) + private LaneDataAttributeList data; + @Asn1Property(tag = 4, optional = true) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 dWidth; + @Asn1Property(tag = 5, optional = true) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 dElevation; + @Asn1Property(tag = 6, optional = true) + private SequenceOfRegional regional; + + public NodeAttributeLLList getLocalNode() { + return localNode; + } + + public void setLocalNode(NodeAttributeLLList localNode) { + this.localNode = localNode; + } + + public SegmentAttributeLLList getDisabled() { + return disabled; + } + + public void setDisabled(SegmentAttributeLLList disabled) { + this.disabled = disabled; + } + + public SegmentAttributeLLList getEnabled() { + return enabled; + } + + public void setEnabled(SegmentAttributeLLList enabled) { + this.enabled = enabled; + } + + public LaneDataAttributeList getData() { + return data; + } + + public void setData(LaneDataAttributeList data) { + this.data = data; + } + + public Offset_B10 getDWidth() { + return dWidth; + } + + public void setDWidth(Offset_B10 dWidth) { + this.dWidth = dWidth; + } + + public Offset_B10 getDElevation() { + return dElevation; + } + + public void setDElevation(Offset_B10 dElevation) { + this.dElevation = dElevation; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetLL.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + NodeAttributeSetLL() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java new file mode 100644 index 000000000..90d7fdf5f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java @@ -0,0 +1,121 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetXY; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class NodeAttributeSetXY extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + @JsonDeserialize(using = NodeAttributeXYList.NodeAttributeXYListDeserializer.class) + private NodeAttributeXYList localNode; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = SegmentAttributeXYList.SegmentAttributeXYListDeserializer.class) + private SegmentAttributeXYList disabled; + @Asn1Property(tag = 2, optional = true) + @JsonDeserialize(using = SegmentAttributeXYList.SegmentAttributeXYListDeserializer.class) + private SegmentAttributeXYList enabled; + @Asn1Property(tag = 3, optional = true) + @JacksonXmlElementWrapper(useWrapping = false) + private LaneDataAttributeList data; + @Asn1Property(tag = 4, optional = true) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 dWidth; + @Asn1Property(tag = 5, optional = true) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 dElevation; + @Asn1Property(tag = 6, optional = true) + private SequenceOfRegional regional; + + public NodeAttributeXYList getLocalNode() { + return localNode; + } + + public void setLocalNode(NodeAttributeXYList localNode) { + this.localNode = localNode; + } + + public SegmentAttributeXYList getDisabled() { + return disabled; + } + + public void setDisabled(SegmentAttributeXYList disabled) { + this.disabled = disabled; + } + + public SegmentAttributeXYList getEnabled() { + return enabled; + } + + public void setEnabled(SegmentAttributeXYList enabled) { + this.enabled = enabled; + } + + public LaneDataAttributeList getData() { + return data; + } + + public void setData(LaneDataAttributeList data) { + this.data = data; + } + + public Offset_B10 getDWidth() { + return dWidth; + } + + public void setDWidth(Offset_B10 dWidth) { + this.dWidth = dWidth; + } + + public Offset_B10 getDElevation() { + return dElevation; + } + + public void setDElevation(Offset_B10 dElevation) { + this.dElevation = dElevation; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetXY.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + NodeAttributeSetXY() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java new file mode 100644 index 000000000..b404926b1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java @@ -0,0 +1,56 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = NodeAttributeXYSerializer.class) +@JsonDeserialize(using = NodeAttributeXYDeserializer.class) +public enum NodeAttributeXY implements Asn1Enumerated { + reserved(0, "reserved"), stopLine(1, "stopLine"), roundedCapStyleA(2, "roundedCapStyleA"), roundedCapStyleB(3, + "roundedCapStyleB"), mergePoint(4, "mergePoint"), divergePoint(5, "divergePoint"), downstreamStopLine(6, + "downstreamStopLine"), downstreamStartNode(7, "downstreamStartNode"), closedToTraffic(8, + "closedToTraffic"), safeIsland(9, "safeIsland"), curbPresentAtStepOff(10, + "curbPresentAtStepOff"), hydrantPresent(11, "hydrantPresent"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private NodeAttributeXY(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 11; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java new file mode 100644 index 000000000..e4e7cde86 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeAttributeXYDeserializer extends EnumeratedDeserializer { + + NodeAttributeXYDeserializer() { + super(NodeAttributeXY.class); + } + + @Override + protected NodeAttributeXY[] listEnumValues() { + return NodeAttributeXY.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java new file mode 100644 index 000000000..311899d28 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeAttributeXYList extends Asn1SequenceOf { + + NodeAttributeXYList() { + super(NodeAttributeXY.class, 1L, 8L); + } + + public static class NodeAttributeXYListDeserializer + extends + SequenceOfEnumeratedDeserializer { + public NodeAttributeXYListDeserializer() { + super(NodeAttributeXYList.class, NodeAttributeXY.class); + } + + @Override + protected NodeAttributeXY[] listEnumValues() { + return NodeAttributeXY.values(); + } + + @Override + protected NodeAttributeXYList construct() { + return new NodeAttributeXYList(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java new file mode 100644 index 000000000..35d331c1c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class NodeAttributeXYSerializer extends EnumeratedSerializer { + + NodeAttributeXYSerializer() { + super(NodeAttributeXY.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java new file mode 100644 index 000000000..be8451ddf --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class NodeLL extends Asn1Sequence { + + @Asn1Property(tag = 0) + private NodeOffsetPointLL delta; + @Asn1Property(tag = 1, optional = true) + private NodeAttributeSetLL attributes; + + public NodeOffsetPointLL getDelta() { + return delta; + } + + public void setDelta(NodeOffsetPointLL delta) { + this.delta = delta; + } + + public NodeAttributeSetLL getAttributes() { + return attributes; + } + + public void setAttributes(NodeAttributeSetLL attributes) { + this.attributes = attributes; + } + + NodeLL() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java new file mode 100644 index 000000000..dfcc6f6d8 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeListLL extends Asn1Choice { + + @Asn1Property(tag = 0) + @JacksonXmlElementWrapper(localName = "nodes") + @JacksonXmlProperty(localName = "NodeLL") + private NodeSetLL nodes; + + NodeListLL() { + super(true); + } + + public NodeSetLL getNodes() { + return nodes; + } + + public void setNodes(NodeSetLL nodes) { + this.nodes = nodes; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java new file mode 100644 index 000000000..8c1389e32 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java @@ -0,0 +1,64 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeListXY extends Asn1Choice { + + @Asn1Property(tag = 0) + @JacksonXmlElementWrapper(localName = "nodes") + @JacksonXmlProperty(localName = "NodeXY") + private NodeSetXY nodes; + @Asn1Property(tag = 1) + private ComputedLane computed; + + NodeListXY() { + super(true); + } + + public NodeSetXY getNodes() { + return nodes; + } + + public void setNodes(NodeSetXY nodes) { + this.nodes = nodes; + } + + public ComputedLane getComputed() { + return computed; + } + + public void setComputed(ComputedLane computed) { + this.computed = computed; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java new file mode 100644 index 000000000..b7c789e95 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java @@ -0,0 +1,129 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.annotation.JsonProperty; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointLL; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeOffsetPointLL extends Asn1Choice { + + @Asn1Property(tag = 0, name = "node-LL1") + @JsonProperty("node-LL1") + private Node_LL_24B node_LL1; + @Asn1Property(tag = 1, name = "node-LL2") + @JsonProperty("node-LL2") + private Node_LL_28B node_LL2; + @Asn1Property(tag = 2, name = "node-LL3") + @JsonProperty("node-LL3") + private Node_LL_32B node_LL3; + @Asn1Property(tag = 3, name = "node-LL4") + @JsonProperty("node-LL4") + private Node_LL_36B node_LL4; + @Asn1Property(tag = 4, name = "node-LL5") + @JsonProperty("node-LL5") + private Node_LL_44B node_LL5; + @Asn1Property(tag = 5, name = "node-LL6") + @JsonProperty("node-LL6") + private Node_LL_48B node_LL6; + @Asn1Property(tag = 6, name = "node-LatLon") + @JsonProperty("node-LatLon") + private Node_LLmD_64b node_LatLon; + @Asn1Property(tag = 7) + private Reg_NodeOffsetPointLL regional; + + NodeOffsetPointLL() { + super(false); + } + + public Node_LL_24B getNode_LL1() { + return node_LL1; + } + + public void setNode_LL1(Node_LL_24B node_LL1) { + this.node_LL1 = node_LL1; + } + + public Node_LL_28B getNode_LL2() { + return node_LL2; + } + + public void setNode_LL2(Node_LL_28B node_LL2) { + this.node_LL2 = node_LL2; + } + + public Node_LL_32B getNode_LL3() { + return node_LL3; + } + + public void setNode_LL3(Node_LL_32B node_LL3) { + this.node_LL3 = node_LL3; + } + + public Node_LL_36B getNode_LL4() { + return node_LL4; + } + + public void setNode_LL4(Node_LL_36B node_LL4) { + this.node_LL4 = node_LL4; + } + + public Node_LL_44B getNode_LL5() { + return node_LL5; + } + + public void setNode_LL5(Node_LL_44B node_LL5) { + this.node_LL5 = node_LL5; + } + + public Node_LL_48B getNode_LL6() { + return node_LL6; + } + + public void setNode_LL6(Node_LL_48B node_LL6) { + this.node_LL6 = node_LL6; + } + + public Node_LLmD_64b getNode_LatLon() { + return node_LatLon; + } + + public void setNode_LatLon(Node_LLmD_64b node_LatLon) { + this.node_LatLon = node_LatLon; + } + + public Reg_NodeOffsetPointLL getRegional() { + return regional; + } + + public void setRegional(Reg_NodeOffsetPointLL regional) { + this.regional = regional; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java new file mode 100644 index 000000000..834ab5f18 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java @@ -0,0 +1,129 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.annotation.JsonProperty; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointXY; +import java.util.Optional; +import java.util.List; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeOffsetPointXY extends Asn1Choice { + + @Asn1Property(tag = 0, name = "node-XY1") + @JsonProperty("node-XY1") + private Node_XY_20b node_XY1; + @Asn1Property(tag = 1, name = "node-XY2") + @JsonProperty("node-XY2") + private Node_XY_22b node_XY2; + @Asn1Property(tag = 2, name = "node-XY3") + @JsonProperty("node-XY3") + private Node_XY_24b node_XY3; + @Asn1Property(tag = 3, name = "node-XY4") + @JsonProperty("node-XY4") + private Node_XY_26b node_XY4; + @Asn1Property(tag = 4, name = "node-XY5") + @JsonProperty("node-XY5") + private Node_XY_28b node_XY5; + @Asn1Property(tag = 5, name = "node-XY6") + @JsonProperty("node-XY6") + private Node_XY_32b node_XY6; + @Asn1Property(tag = 6, name = "node-LatLon") + @JsonProperty("node-LatLon") + private Node_LLmD_64b node_LatLon; + @Asn1Property(tag = 7) + private Reg_NodeOffsetPointXY regional; + + NodeOffsetPointXY() { + super(false); + } + + public Node_XY_20b getNode_XY1() { + return node_XY1; + } + + public void setNode_XY1(Node_XY_20b node_XY1) { + this.node_XY1 = node_XY1; + } + + public Node_XY_22b getNode_XY2() { + return node_XY2; + } + + public void setNode_XY2(Node_XY_22b node_XY2) { + this.node_XY2 = node_XY2; + } + + public Node_XY_24b getNode_XY3() { + return node_XY3; + } + + public void setNode_XY3(Node_XY_24b node_XY3) { + this.node_XY3 = node_XY3; + } + + public Node_XY_26b getNode_XY4() { + return node_XY4; + } + + public void setNode_XY4(Node_XY_26b node_XY4) { + this.node_XY4 = node_XY4; + } + + public Node_XY_28b getNode_XY5() { + return node_XY5; + } + + public void setNode_XY5(Node_XY_28b node_XY5) { + this.node_XY5 = node_XY5; + } + + public Node_XY_32b getNode_XY6() { + return node_XY6; + } + + public void setNode_XY6(Node_XY_32b node_XY6) { + this.node_XY6 = node_XY6; + } + + public Node_LLmD_64b getNode_LatLon() { + return node_LatLon; + } + + public void setNode_LatLon(Node_LLmD_64b node_LatLon) { + this.node_LatLon = node_LatLon; + } + + public Reg_NodeOffsetPointXY getRegional() { + return regional; + } + + public void setRegional(Reg_NodeOffsetPointXY regional) { + this.regional = regional; + } + + @Override + protected List> listTypes() { + return null; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java new file mode 100644 index 000000000..2e81ff5d0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeSetLL extends Asn1SequenceOf { + + NodeSetLL() { + super(NodeLL.class, 2L, 63L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java new file mode 100644 index 000000000..880fcbac7 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class NodeSetXY extends Asn1SequenceOf { + + NodeSetXY() { + super(NodeXY.class, 2L, 63L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java new file mode 100644 index 000000000..cc421bf85 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class NodeXY extends Asn1Sequence { + + @Asn1Property(tag = 0) + private NodeOffsetPointXY delta; + @Asn1Property(tag = 1, optional = true) + private NodeAttributeSetXY attributes; + + public NodeOffsetPointXY getDelta() { + return delta; + } + + public void setDelta(NodeOffsetPointXY delta) { + this.delta = delta; + } + + public NodeAttributeSetXY getAttributes() { + return attributes; + } + + public void setAttributes(NodeAttributeSetXY attributes) { + this.attributes = attributes; + } + + NodeXY() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java new file mode 100644 index 000000000..cafdac04e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_24B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) + private OffsetLL_B12 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) + private OffsetLL_B12 lat; + + public OffsetLL_B12 getLon() { + return lon; + } + + public void setLon(OffsetLL_B12 lon) { + this.lon = lon; + } + + public OffsetLL_B12 getLat() { + return lat; + } + + public void setLat(OffsetLL_B12 lat) { + this.lat = lat; + } + + Node_LL_24B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java new file mode 100644 index 000000000..4aa6d9b66 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_28B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) + private OffsetLL_B14 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) + private OffsetLL_B14 lat; + + public OffsetLL_B14 getLon() { + return lon; + } + + public void setLon(OffsetLL_B14 lon) { + this.lon = lon; + } + + public OffsetLL_B14 getLat() { + return lat; + } + + public void setLat(OffsetLL_B14 lat) { + this.lat = lat; + } + + Node_LL_28B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java new file mode 100644 index 000000000..bb16587be --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_32B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + private OffsetLL_B16 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + private OffsetLL_B16 lat; + + public OffsetLL_B16 getLon() { + return lon; + } + + public void setLon(OffsetLL_B16 lon) { + this.lon = lon; + } + + public OffsetLL_B16 getLat() { + return lat; + } + + public void setLat(OffsetLL_B16 lat) { + this.lat = lat; + } + + Node_LL_32B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java new file mode 100644 index 000000000..2397c1578 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_36B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) + private OffsetLL_B18 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) + private OffsetLL_B18 lat; + + public OffsetLL_B18 getLon() { + return lon; + } + + public void setLon(OffsetLL_B18 lon) { + this.lon = lon; + } + + public OffsetLL_B18 getLat() { + return lat; + } + + public void setLat(OffsetLL_B18 lat) { + this.lat = lat; + } + + Node_LL_36B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java new file mode 100644 index 000000000..2646045ff --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_44B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) + private OffsetLL_B22 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) + private OffsetLL_B22 lat; + + public OffsetLL_B22 getLon() { + return lon; + } + + public void setLon(OffsetLL_B22 lon) { + this.lon = lon; + } + + public OffsetLL_B22 getLat() { + return lat; + } + + public void setLat(OffsetLL_B22 lat) { + this.lat = lat; + } + + Node_LL_44B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java new file mode 100644 index 000000000..ea50e345e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LL_48B extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) + private OffsetLL_B24 lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) + private OffsetLL_B24 lat; + + public OffsetLL_B24 getLon() { + return lon; + } + + public void setLon(OffsetLL_B24 lon) { + this.lon = lon; + } + + public OffsetLL_B24 getLat() { + return lat; + } + + public void setLat(OffsetLL_B24 lat) { + this.lat = lat; + } + + Node_LL_48B() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java new file mode 100644 index 000000000..2606a44da --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_LLmD_64b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Longitude.LongitudeDeserializer.class) + private Longitude lon; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Latitude.LatitudeDeserializer.class) + private Latitude lat; + + public Longitude getLon() { + return lon; + } + + public void setLon(Longitude lon) { + this.lon = lon; + } + + public Latitude getLat() { + return lat; + } + + public void setLat(Latitude lat) { + this.lat = lat; + } + + Node_LLmD_64b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java new file mode 100644 index 000000000..f17e29f10 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_20b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + private Offset_B10 y; + + public Offset_B10 getX() { + return x; + } + + public void setX(Offset_B10 x) { + this.x = x; + } + + public Offset_B10 getY() { + return y; + } + + public void setY(Offset_B10 y) { + this.y = y; + } + + Node_XY_20b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java new file mode 100644 index 000000000..22f230750 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_22b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) + private Offset_B11 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) + private Offset_B11 y; + + public Offset_B11 getX() { + return x; + } + + public void setX(Offset_B11 x) { + this.x = x; + } + + public Offset_B11 getY() { + return y; + } + + public void setY(Offset_B11 y) { + this.y = y; + } + + Node_XY_22b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java new file mode 100644 index 000000000..4f3496f66 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_24b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) + private Offset_B12 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) + private Offset_B12 y; + + public Offset_B12 getX() { + return x; + } + + public void setX(Offset_B12 x) { + this.x = x; + } + + public Offset_B12 getY() { + return y; + } + + public void setY(Offset_B12 y) { + this.y = y; + } + + Node_XY_24b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java new file mode 100644 index 000000000..ba0775433 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_26b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) + private Offset_B13 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) + private Offset_B13 y; + + public Offset_B13 getX() { + return x; + } + + public void setX(Offset_B13 x) { + this.x = x; + } + + public Offset_B13 getY() { + return y; + } + + public void setY(Offset_B13 y) { + this.y = y; + } + + Node_XY_26b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java new file mode 100644 index 000000000..4ce74eb15 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_28b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) + private Offset_B14 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) + private Offset_B14 y; + + public Offset_B14 getX() { + return x; + } + + public void setX(Offset_B14 x) { + this.x = x; + } + + public Offset_B14 getY() { + return y; + } + + public void setY(Offset_B14 y) { + this.y = y; + } + + Node_XY_28b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java new file mode 100644 index 000000000..90ee3098a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Node_XY_32b extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) + private Offset_B16 x; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) + private Offset_B16 y; + + public Offset_B16 getX() { + return x; + } + + public void setX(Offset_B16 x) { + this.x = x; + } + + public Offset_B16 getY() { + return y; + } + + public void setY(Offset_B16 y) { + this.y = y; + } + + Node_XY_32b() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java new file mode 100644 index 000000000..f282c913d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B12 extends Asn1Integer { + + public OffsetLL_B12() { + super(-2048L, 2047L); + } + + @JsonCreator + public OffsetLL_B12(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B12Deserializer extends IntegerDeserializer { + public OffsetLL_B12Deserializer() { + super(OffsetLL_B12.class); + } + + @Override + protected OffsetLL_B12 construct() { + return new OffsetLL_B12(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java new file mode 100644 index 000000000..b072d3e1c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B14 extends Asn1Integer { + + public OffsetLL_B14() { + super(-8192L, 8191L); + } + + @JsonCreator + public OffsetLL_B14(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B14Deserializer extends IntegerDeserializer { + public OffsetLL_B14Deserializer() { + super(OffsetLL_B14.class); + } + + @Override + protected OffsetLL_B14 construct() { + return new OffsetLL_B14(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java new file mode 100644 index 000000000..858fe7db1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B16 extends Asn1Integer { + + public OffsetLL_B16() { + super(-32768L, 32767L); + } + + @JsonCreator + public OffsetLL_B16(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B16Deserializer extends IntegerDeserializer { + public OffsetLL_B16Deserializer() { + super(OffsetLL_B16.class); + } + + @Override + protected OffsetLL_B16 construct() { + return new OffsetLL_B16(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java new file mode 100644 index 000000000..a3c10390d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B18 extends Asn1Integer { + + public OffsetLL_B18() { + super(-131072L, 131071L); + } + + @JsonCreator + public OffsetLL_B18(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B18Deserializer extends IntegerDeserializer { + public OffsetLL_B18Deserializer() { + super(OffsetLL_B18.class); + } + + @Override + protected OffsetLL_B18 construct() { + return new OffsetLL_B18(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java new file mode 100644 index 000000000..e7cb154cf --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B22 extends Asn1Integer { + + public OffsetLL_B22() { + super(-2097152L, 2097151L); + } + + @JsonCreator + public OffsetLL_B22(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B22Deserializer extends IntegerDeserializer { + public OffsetLL_B22Deserializer() { + super(OffsetLL_B22.class); + } + + @Override + protected OffsetLL_B22 construct() { + return new OffsetLL_B22(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java new file mode 100644 index 000000000..43fc5e189 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class OffsetLL_B24 extends Asn1Integer { + + public OffsetLL_B24() { + super(-8388608L, 8388607L); + } + + @JsonCreator + public OffsetLL_B24(long value) { + this(); + this.value = value; + } + + public static class OffsetLL_B24Deserializer extends IntegerDeserializer { + public OffsetLL_B24Deserializer() { + super(OffsetLL_B24.class); + } + + @Override + protected OffsetLL_B24 construct() { + return new OffsetLL_B24(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java new file mode 100644 index 000000000..97f5bec2e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java @@ -0,0 +1,93 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class OffsetSystem extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + @JsonDeserialize(using = Zoom.ZoomDeserializer.class) + private Zoom scale; + @Asn1Property(tag = 1) + private OffsetChoice offset; + + public Zoom getScale() { + return scale; + } + + public void setScale(Zoom scale) { + this.scale = scale; + } + + @JsonInclude(Include.NON_NULL) + public static class OffsetChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private NodeListXY xy; + @Asn1Property(tag = 1) + private NodeListLL ll; + + OffsetChoice() { + super(false); + } + + public NodeListXY getXy() { + return xy; + } + + public void setXy(NodeListXY xy) { + this.xy = xy; + } + + public NodeListLL getLl() { + return ll; + } + + public void setLl(NodeListLL ll) { + this.ll = ll; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public OffsetChoice getOffset() { + return offset; + } + + public void setOffset(OffsetChoice offset) { + this.offset = offset; + } + + OffsetSystem() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java new file mode 100644 index 000000000..ad6e0e1bd --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B10 extends Asn1Integer { + + public Offset_B10() { + super(-512L, 511L); + } + + @JsonCreator + public Offset_B10(long value) { + this(); + this.value = value; + } + + public static class Offset_B10Deserializer extends IntegerDeserializer { + public Offset_B10Deserializer() { + super(Offset_B10.class); + } + + @Override + protected Offset_B10 construct() { + return new Offset_B10(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java new file mode 100644 index 000000000..7e725904b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B11 extends Asn1Integer { + + public Offset_B11() { + super(-1024L, 1023L); + } + + @JsonCreator + public Offset_B11(long value) { + this(); + this.value = value; + } + + public static class Offset_B11Deserializer extends IntegerDeserializer { + public Offset_B11Deserializer() { + super(Offset_B11.class); + } + + @Override + protected Offset_B11 construct() { + return new Offset_B11(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java new file mode 100644 index 000000000..1e3b29519 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B12 extends Asn1Integer { + + public Offset_B12() { + super(-2048L, 2047L); + } + + @JsonCreator + public Offset_B12(long value) { + this(); + this.value = value; + } + + public static class Offset_B12Deserializer extends IntegerDeserializer { + public Offset_B12Deserializer() { + super(Offset_B12.class); + } + + @Override + protected Offset_B12 construct() { + return new Offset_B12(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java new file mode 100644 index 000000000..97cee3e55 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B13 extends Asn1Integer { + + public Offset_B13() { + super(-4096L, 4095L); + } + + @JsonCreator + public Offset_B13(long value) { + this(); + this.value = value; + } + + public static class Offset_B13Deserializer extends IntegerDeserializer { + public Offset_B13Deserializer() { + super(Offset_B13.class); + } + + @Override + protected Offset_B13 construct() { + return new Offset_B13(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java new file mode 100644 index 000000000..1c16d7d4a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B14 extends Asn1Integer { + + public Offset_B14() { + super(-8192L, 8191L); + } + + @JsonCreator + public Offset_B14(long value) { + this(); + this.value = value; + } + + public static class Offset_B14Deserializer extends IntegerDeserializer { + public Offset_B14Deserializer() { + super(Offset_B14.class); + } + + @Override + protected Offset_B14 construct() { + return new Offset_B14(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java new file mode 100644 index 000000000..78413d799 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Offset_B16 extends Asn1Integer { + + public Offset_B16() { + super(-32768L, 32767L); + } + + @JsonCreator + public Offset_B16(long value) { + this(); + this.value = value; + } + + public static class Offset_B16Deserializer extends IntegerDeserializer { + public Offset_B16Deserializer() { + super(Offset_B16.class); + } + + @Override + protected Offset_B16 construct() { + return new Offset_B16(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java new file mode 100644 index 000000000..1bc3db597 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java @@ -0,0 +1,89 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.annotation.JsonProperty; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Position3D extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = Latitude.LatitudeDeserializer.class) + private Latitude lat; + @Asn1Property(tag = 1, name = "long") + @JsonProperty("long") + @JsonDeserialize(using = Longitude.LongitudeDeserializer.class) + private Longitude long_; + @Asn1Property(tag = 2, optional = true) + @JsonDeserialize(using = Elevation.ElevationDeserializer.class) + private Elevation elevation; + @Asn1Property(tag = 3, optional = true) + private SequenceOfRegional regional; + + public Latitude getLat() { + return lat; + } + + public void setLat(Latitude lat) { + this.lat = lat; + } + + public Longitude getLong_() { + return long_; + } + + public void setLong_(Longitude long_) { + this.long_ = long_; + } + + public Elevation getElevation() { + return elevation; + } + + public void setElevation(Elevation elevation) { + this.elevation = elevation; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + Position3D() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java new file mode 100644 index 000000000..3afbfed59 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Radius_B12 extends Asn1Integer { + + public Radius_B12() { + super(0L, 4095L); + } + + @JsonCreator + public Radius_B12(long value) { + this(); + this.value = value; + } + + public static class Radius_B12Deserializer extends IntegerDeserializer { + public Radius_B12Deserializer() { + super(Radius_B12.class); + } + + @Override + protected Radius_B12 construct() { + return new Radius_B12(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java new file mode 100644 index 000000000..82bbe65ef --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class RegionId extends Asn1Integer { + + public RegionId() { + super(0L, 255L); + } + + @JsonCreator + public RegionId(long value) { + this(); + this.value = value; + } + + public static class RegionIdDeserializer extends IntegerDeserializer { + public RegionIdDeserializer() { + super(RegionId.class); + } + + @Override + protected RegionId construct() { + return new RegionId(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java new file mode 100644 index 000000000..2a179fda2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class RegionList extends Asn1SequenceOf { + + RegionList() { + super(RegionOffsets.class, 1L, 64L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java new file mode 100644 index 000000000..61437bc13 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java @@ -0,0 +1,68 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RegionOffsets extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + private OffsetLL_B16 xOffset; + @Asn1Property(tag = 1) + @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + private OffsetLL_B16 yOffset; + @Asn1Property(tag = 2, optional = true) + @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + private OffsetLL_B16 zOffset; + + public OffsetLL_B16 getXOffset() { + return xOffset; + } + + public void setXOffset(OffsetLL_B16 xOffset) { + this.xOffset = xOffset; + } + + public OffsetLL_B16 getYOffset() { + return yOffset; + } + + public void setYOffset(OffsetLL_B16 yOffset) { + this.yOffset = yOffset; + } + + public OffsetLL_B16 getZOffset() { + return zOffset; + } + + public void setZOffset(OffsetLL_B16 zOffset) { + this.zOffset = zOffset; + } + + RegionOffsets() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java new file mode 100644 index 000000000..a2c133bfb --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java @@ -0,0 +1,70 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RegionPointSet extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + private Position3D anchor; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = Zoom.ZoomDeserializer.class) + private Zoom scale; + @Asn1Property(tag = 2) + @JacksonXmlElementWrapper(localName = "nodeList") + @JacksonXmlProperty(localName = "RegionOffsets") + private RegionList nodeList; + + public Position3D getAnchor() { + return anchor; + } + + public void setAnchor(Position3D anchor) { + this.anchor = anchor; + } + + public Zoom getScale() { + return scale; + } + + public void setScale(Zoom scale) { + this.scale = scale; + } + + public RegionList getNodeList() { + return nodeList; + } + + public void setNodeList(RegionList nodeList) { + this.nodeList = nodeList; + } + + RegionPointSet() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java new file mode 100644 index 000000000..2c029c459 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java @@ -0,0 +1,63 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +abstract public class RegionalExtension extends Asn1Sequence { + + @JsonIgnore + @JsonDeserialize(using = RegionId.RegionIdDeserializer.class) + final protected RegionId regionId; + @JsonIgnore + final protected String name; + private TValue regExtValue; + public final static String INFORMATION_OBJECT_CLASS = "REG_EXT_ID_AND_TYPE"; + + public RegionId getRegionId() { + return regionId; + } + + public String getName() { + return name; + } + + @JsonProperty("regionId") + public String getIdString() { + return regionId.toString(); + } + + public TValue getRegExtValue() { + return regExtValue; + } + + public void setRegExtValue(TValue regExtValue) { + this.regExtValue = regExtValue; + } + + public RegionalExtension(int id, String name) { + super(true); + var theId = new RegionId(); + theId.setValue(id); + this.regionId = theId; + this.name = name; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java new file mode 100644 index 000000000..752adcad7 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java @@ -0,0 +1,56 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RegulatorySpeedLimit extends Asn1Sequence { + + @Asn1Property(tag = 0) + private SpeedLimitType type; + @Asn1Property(tag = 1) + @JsonDeserialize(using = Velocity.VelocityDeserializer.class) + private Velocity speed; + + public SpeedLimitType getType() { + return type; + } + + public void setType(SpeedLimitType type) { + this.type = type; + } + + public Velocity getSpeed() { + return speed; + } + + public void setSpeed(Velocity speed) { + this.speed = speed; + } + + RegulatorySpeedLimit() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java new file mode 100644 index 000000000..cbc2e5cc0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class RoadRegulatorID extends Asn1Integer { + + public RoadRegulatorID() { + super(0L, 65535L); + } + + @JsonCreator + public RoadRegulatorID(long value) { + this(); + this.value = value; + } + + public static class RoadRegulatorIDDeserializer extends IntegerDeserializer { + public RoadRegulatorIDDeserializer() { + super(RoadRegulatorID.class); + } + + @Override + protected RoadRegulatorID construct() { + return new RoadRegulatorID(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java new file mode 100644 index 000000000..e776a933c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class RoadSegmentID extends Asn1Integer { + + public RoadSegmentID() { + super(0L, 65535L); + } + + @JsonCreator + public RoadSegmentID(long value) { + this(); + this.value = value; + } + + public static class RoadSegmentIDDeserializer extends IntegerDeserializer { + public RoadSegmentIDDeserializer() { + super(RoadSegmentID.class); + } + + @Override + protected RoadSegmentID construct() { + return new RoadSegmentID(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java new file mode 100644 index 000000000..5ba6bfc45 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java @@ -0,0 +1,57 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RoadSegmentReferenceID extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + @JsonDeserialize(using = RoadRegulatorID.RoadRegulatorIDDeserializer.class) + private RoadRegulatorID region; + @Asn1Property(tag = 1) + @JsonDeserialize(using = RoadSegmentID.RoadSegmentIDDeserializer.class) + private RoadSegmentID id; + + public RoadRegulatorID getRegion() { + return region; + } + + public void setRegion(RoadRegulatorID region) { + this.region = region; + } + + public RoadSegmentID getId() { + return id; + } + + public void setId(RoadSegmentID id) { + this.id = id; + } + + RoadSegmentReferenceID() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java new file mode 100644 index 000000000..c934089d4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java @@ -0,0 +1,74 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class RoadSignID extends Asn1Sequence { + + @Asn1Property(tag = 0) + private Position3D position; + @Asn1Property(tag = 1) + private HeadingSlice viewAngle; + @Asn1Property(tag = 2, optional = true) + private MUTCDCode mutcdCode; + @Asn1Property(tag = 3, optional = true) + private MsgCRC crc; + + public Position3D getPosition() { + return position; + } + + public void setPosition(Position3D position) { + this.position = position; + } + + public HeadingSlice getViewAngle() { + return viewAngle; + } + + public void setViewAngle(HeadingSlice viewAngle) { + this.viewAngle = viewAngle; + } + + public MUTCDCode getMutcdCode() { + return mutcdCode; + } + + public void setMutcdCode(MUTCDCode mutcdCode) { + this.mutcdCode = mutcdCode; + } + + public MsgCRC getCrc() { + return crc; + } + + public void setCrc(MsgCRC crc) { + this.crc = crc; + } + + RoadSignID() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java new file mode 100644 index 000000000..b0ece2916 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class RoadwayCrownAngle extends Asn1Integer { + + public RoadwayCrownAngle() { + super(-128L, 127L); + } + + @JsonCreator + public RoadwayCrownAngle(long value) { + this(); + this.value = value; + } + + public static class RoadwayCrownAngleDeserializer extends IntegerDeserializer { + public RoadwayCrownAngleDeserializer() { + super(RoadwayCrownAngle.class); + } + + @Override + protected RoadwayCrownAngle construct() { + return new RoadwayCrownAngle(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java new file mode 100644 index 000000000..fef0ff80d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SSPindex extends Asn1Integer { + + public SSPindex() { + super(0L, 31L); + } + + @JsonCreator + public SSPindex(long value) { + this(); + this.value = value; + } + + public static class SSPindexDeserializer extends IntegerDeserializer { + public SSPindexDeserializer() { + super(SSPindex.class); + } + + @Override + protected SSPindex construct() { + return new SSPindex(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java new file mode 100644 index 000000000..0a712a5fb --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Scale_B12 extends Asn1Integer { + + public Scale_B12() { + super(-2048L, 2047L); + } + + @JsonCreator + public Scale_B12(long value) { + this(); + this.value = value; + } + + public static class Scale_B12Deserializer extends IntegerDeserializer { + public Scale_B12Deserializer() { + super(Scale_B12.class); + } + + @Override + protected Scale_B12 construct() { + return new Scale_B12(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java new file mode 100644 index 000000000..fbf188d3c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java @@ -0,0 +1,104 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = SegmentAttributeLLSerializer.class) +@JsonDeserialize(using = SegmentAttributeLLDeserializer.class) +public enum SegmentAttributeLL implements Asn1Enumerated { + reserved(0, "reserved"), doNotBlock(1, "doNotBlock"), whiteLine(2, "whiteLine"), mergingLaneLeft(3, + "mergingLaneLeft"), mergingLaneRight(4, "mergingLaneRight"), curbOnLeft(5, "curbOnLeft"), curbOnRight(6, + "curbOnRight"), loadingzoneOnLeft(7, "loadingzoneOnLeft"), loadingzoneOnRight(8, + "loadingzoneOnRight"), turnOutPointOnLeft(9, "turnOutPointOnLeft"), turnOutPointOnRight(10, + "turnOutPointOnRight"), adjacentParkingOnLeft(11, + "adjacentParkingOnLeft"), adjacentParkingOnRight(12, + "adjacentParkingOnRight"), adjacentBikeLaneOnLeft(13, + "adjacentBikeLaneOnLeft"), adjacentBikeLaneOnRight(14, + "adjacentBikeLaneOnRight"), sharedBikeLane(15, + "sharedBikeLane"), bikeBoxInFront(16, + "bikeBoxInFront"), transitStopOnLeft( + 17, + "transitStopOnLeft"), transitStopOnRight( + 18, + "transitStopOnRight"), transitStopInLane( + 19, + "transitStopInLane"), sharedWithTrackedVehicle( + 20, + "sharedWithTrackedVehicle"), safeIsland( + 21, + "safeIsland"), lowCurbsPresent( + 22, + "lowCurbsPresent"), rumbleStripPresent( + 23, + "rumbleStripPresent"), audibleSignalingPresent( + 24, + "audibleSignalingPresent"), adaptiveTimingPresent( + 25, + "adaptiveTimingPresent"), rfSignalRequestPresent( + 26, + "rfSignalRequestPresent"), partialCurbIntrusion( + 27, + "partialCurbIntrusion"), taperToLeft( + 28, + "taperToLeft"), taperToRight( + 29, + "taperToRight"), taperToCenterLine( + 30, + "taperToCenterLine"), parallelParking( + 31, + "parallelParking"), headInParking( + 32, + "headInParking"), freeParking( + 33, + "freeParking"), timeRestrictionsOnParking( + 34, + "timeRestrictionsOnParking"), costToPark( + 35, + "costToPark"), midBlockCurbPresent( + 36, + "midBlockCurbPresent"), unEvenPavementPresent( + 37, + "unEvenPavementPresent"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private SegmentAttributeLL(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 37; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java new file mode 100644 index 000000000..b5820113e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SegmentAttributeLLDeserializer extends EnumeratedDeserializer { + + SegmentAttributeLLDeserializer() { + super(SegmentAttributeLL.class); + } + + @Override + protected SegmentAttributeLL[] listEnumValues() { + return SegmentAttributeLL.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java new file mode 100644 index 000000000..70e3a8055 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class SegmentAttributeLLList extends Asn1SequenceOf { + + SegmentAttributeLLList() { + super(SegmentAttributeLL.class, 1L, 8L); + } + + public static class SegmentAttributeLLListDeserializer + extends + SequenceOfEnumeratedDeserializer { + public SegmentAttributeLLListDeserializer() { + super(SegmentAttributeLLList.class, SegmentAttributeLL.class); + } + + @Override + protected SegmentAttributeLL[] listEnumValues() { + return SegmentAttributeLL.values(); + } + + @Override + protected SegmentAttributeLLList construct() { + return new SegmentAttributeLLList(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java new file mode 100644 index 000000000..13786839f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SegmentAttributeLLSerializer extends EnumeratedSerializer { + + SegmentAttributeLLSerializer() { + super(SegmentAttributeLL.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java new file mode 100644 index 000000000..db8bb5d45 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java @@ -0,0 +1,104 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = SegmentAttributeXYSerializer.class) +@JsonDeserialize(using = SegmentAttributeXYDeserializer.class) +public enum SegmentAttributeXY implements Asn1Enumerated { + reserved(0, "reserved"), doNotBlock(1, "doNotBlock"), whiteLine(2, "whiteLine"), mergingLaneLeft(3, + "mergingLaneLeft"), mergingLaneRight(4, "mergingLaneRight"), curbOnLeft(5, "curbOnLeft"), curbOnRight(6, + "curbOnRight"), loadingzoneOnLeft(7, "loadingzoneOnLeft"), loadingzoneOnRight(8, + "loadingzoneOnRight"), turnOutPointOnLeft(9, "turnOutPointOnLeft"), turnOutPointOnRight(10, + "turnOutPointOnRight"), adjacentParkingOnLeft(11, + "adjacentParkingOnLeft"), adjacentParkingOnRight(12, + "adjacentParkingOnRight"), adjacentBikeLaneOnLeft(13, + "adjacentBikeLaneOnLeft"), adjacentBikeLaneOnRight(14, + "adjacentBikeLaneOnRight"), sharedBikeLane(15, + "sharedBikeLane"), bikeBoxInFront(16, + "bikeBoxInFront"), transitStopOnLeft( + 17, + "transitStopOnLeft"), transitStopOnRight( + 18, + "transitStopOnRight"), transitStopInLane( + 19, + "transitStopInLane"), sharedWithTrackedVehicle( + 20, + "sharedWithTrackedVehicle"), safeIsland( + 21, + "safeIsland"), lowCurbsPresent( + 22, + "lowCurbsPresent"), rumbleStripPresent( + 23, + "rumbleStripPresent"), audibleSignalingPresent( + 24, + "audibleSignalingPresent"), adaptiveTimingPresent( + 25, + "adaptiveTimingPresent"), rfSignalRequestPresent( + 26, + "rfSignalRequestPresent"), partialCurbIntrusion( + 27, + "partialCurbIntrusion"), taperToLeft( + 28, + "taperToLeft"), taperToRight( + 29, + "taperToRight"), taperToCenterLine( + 30, + "taperToCenterLine"), parallelParking( + 31, + "parallelParking"), headInParking( + 32, + "headInParking"), freeParking( + 33, + "freeParking"), timeRestrictionsOnParking( + 34, + "timeRestrictionsOnParking"), costToPark( + 35, + "costToPark"), midBlockCurbPresent( + 36, + "midBlockCurbPresent"), unEvenPavementPresent( + 37, + "unEvenPavementPresent"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private SegmentAttributeXY(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 37; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java new file mode 100644 index 000000000..d576fd8fc --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SegmentAttributeXYDeserializer extends EnumeratedDeserializer { + + SegmentAttributeXYDeserializer() { + super(SegmentAttributeXY.class); + } + + @Override + protected SegmentAttributeXY[] listEnumValues() { + return SegmentAttributeXY.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java new file mode 100644 index 000000000..ad4328245 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class SegmentAttributeXYList extends Asn1SequenceOf { + + SegmentAttributeXYList() { + super(SegmentAttributeXY.class, 1L, 8L); + } + + public static class SegmentAttributeXYListDeserializer + extends + SequenceOfEnumeratedDeserializer { + public SegmentAttributeXYListDeserializer() { + super(SegmentAttributeXYList.class, SegmentAttributeXY.class); + } + + @Override + protected SegmentAttributeXY[] listEnumValues() { + return SegmentAttributeXY.values(); + } + + @Override + protected SegmentAttributeXYList construct() { + return new SegmentAttributeXYList(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java new file mode 100644 index 000000000..799bf39ee --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SegmentAttributeXYSerializer extends EnumeratedSerializer { + + SegmentAttributeXYSerializer() { + super(SegmentAttributeXY.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java new file mode 100644 index 000000000..40a5e653a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java @@ -0,0 +1,76 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ShapePointSet extends Asn1Sequence { + + @Asn1Property(tag = 0, optional = true) + private Position3D anchor; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + private LaneWidth laneWidth; + @Asn1Property(tag = 2, optional = true) + private DirectionOfUse directionality; + @Asn1Property(tag = 3) + private NodeListXY nodeList; + + public Position3D getAnchor() { + return anchor; + } + + public void setAnchor(Position3D anchor) { + this.anchor = anchor; + } + + public LaneWidth getLaneWidth() { + return laneWidth; + } + + public void setLaneWidth(LaneWidth laneWidth) { + this.laneWidth = laneWidth; + } + + public DirectionOfUse getDirectionality() { + return directionality; + } + + public void setDirectionality(DirectionOfUse directionality) { + this.directionality = directionality; + } + + public NodeListXY getNodeList() { + return nodeList; + } + + public void setNodeList(NodeListXY nodeList) { + this.nodeList = nodeList; + } + + ShapePointSet() { + super(true); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java new file mode 100644 index 000000000..ff7768c97 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SignPrority extends Asn1Integer { + + public SignPrority() { + super(0L, 7L); + } + + @JsonCreator + public SignPrority(long value) { + this(); + this.value = value; + } + + public static class SignProrityDeserializer extends IntegerDeserializer { + public SignProrityDeserializer() { + super(SignPrority.class); + } + + @Override + protected SignPrority construct() { + return new SignPrority(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java new file mode 100644 index 000000000..6c571a6a1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class SpeedLimit extends Asn1SequenceOf { + + SpeedLimit() { + super(SpeedLimitSequence.class, 1L, 16L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java new file mode 100644 index 000000000..c59418f0f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class SpeedLimitList extends Asn1SequenceOf { + + SpeedLimitList() { + super(RegulatorySpeedLimit.class, 1L, 9L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java new file mode 100644 index 000000000..badf6e86a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java @@ -0,0 +1,84 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class SpeedLimitSequence extends Asn1Sequence { + + @Asn1Property(tag = 0) + private ItemChoice item; + + @JsonInclude(Include.NON_NULL) + public static class ItemChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + private ITIScodes itis; + @Asn1Property(tag = 1) + private ITIStextPhrase text; + + ItemChoice() { + super(false); + } + + public ITIScodes getItis() { + return itis; + } + + public void setItis(ITIScodes itis) { + this.itis = itis; + } + + public ITIStextPhrase getText() { + return text; + } + + public void setText(ITIStextPhrase text) { + this.text = text; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ItemChoice getItem() { + return item; + } + + public void setItem(ItemChoice item) { + this.item = item; + } + + SpeedLimitSequence() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java new file mode 100644 index 000000000..a1d936415 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java @@ -0,0 +1,60 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = SpeedLimitTypeSerializer.class) +@JsonDeserialize(using = SpeedLimitTypeDeserializer.class) +public enum SpeedLimitType implements Asn1Enumerated { + unknown(0, "unknown"), maxSpeedInSchoolZone(1, "maxSpeedInSchoolZone"), maxSpeedInSchoolZoneWhenChildrenArePresent( + 2, "maxSpeedInSchoolZoneWhenChildrenArePresent"), maxSpeedInConstructionZone(3, + "maxSpeedInConstructionZone"), vehicleMinSpeed(4, "vehicleMinSpeed"), vehicleMaxSpeed(5, + "vehicleMaxSpeed"), vehicleNightMaxSpeed(6, "vehicleNightMaxSpeed"), truckMinSpeed(7, + "truckMinSpeed"), truckMaxSpeed(8, "truckMaxSpeed"), truckNightMaxSpeed(9, + "truckNightMaxSpeed"), vehiclesWithTrailersMinSpeed(10, + "vehiclesWithTrailersMinSpeed"), vehiclesWithTrailersMaxSpeed(11, + "vehiclesWithTrailersMaxSpeed"), vehiclesWithTrailersNightMaxSpeed( + 12, "vehiclesWithTrailersNightMaxSpeed"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private SpeedLimitType(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 12; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java new file mode 100644 index 000000000..a5eff73e4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SpeedLimitTypeDeserializer extends EnumeratedDeserializer { + + SpeedLimitTypeDeserializer() { + super(SpeedLimitType.class); + } + + @Override + protected SpeedLimitType[] listEnumValues() { + return SpeedLimitType.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java new file mode 100644 index 000000000..6f9482bf0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class SpeedLimitTypeSerializer extends EnumeratedSerializer { + + SpeedLimitTypeSerializer() { + super(SpeedLimitType.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java new file mode 100644 index 000000000..fc868e168 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java @@ -0,0 +1,355 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodesAndText; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TravelerDataFrame extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed; + @Asn1Property(tag = 1) + private TravelerInfoType frameType; + @Asn1Property(tag = 2) + private MsgIdChoice msgId; + @Asn1Property(tag = 3, optional = true) + @JsonDeserialize(using = DYear.DYearDeserializer.class) + private DYear startYear; + @Asn1Property(tag = 4) + @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + private MinuteOfTheYear startTime; + @Asn1Property(tag = 5) + @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) + private MinutesDuration duratonTime; + @Asn1Property(tag = 6) + @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) + private SignPrority priority; + @Asn1Property(tag = 7) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed1; + @Asn1Property(tag = 8) + private SequenceOfRegions regions; + @Asn1Property(tag = 9) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed2; + @Asn1Property(tag = 10) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed3; + @Asn1Property(tag = 11) + private ContentChoice content; + @Asn1Property(tag = 12, optional = true) + private URL_Short url; + + public SSPindex getNotUsed() { + return notUsed; + } + + public void setNotUsed(SSPindex notUsed) { + this.notUsed = notUsed; + } + + public TravelerInfoType getFrameType() { + return frameType; + } + + public void setFrameType(TravelerInfoType frameType) { + this.frameType = frameType; + } + + @JsonInclude(Include.NON_NULL) + public static class MsgIdChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private FurtherInfoID furtherInfoID; + @Asn1Property(tag = 1) + private RoadSignID roadSignID; + + MsgIdChoice() { + super(false); + } + + public FurtherInfoID getFurtherInfoID() { + return furtherInfoID; + } + + public void setFurtherInfoID(FurtherInfoID furtherInfoID) { + this.furtherInfoID = furtherInfoID; + } + + public RoadSignID getRoadSignID() { + return roadSignID; + } + + public void setRoadSignID(RoadSignID roadSignID) { + this.roadSignID = roadSignID; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public MsgIdChoice getMsgId() { + return msgId; + } + + public void setMsgId(MsgIdChoice msgId) { + this.msgId = msgId; + } + + public DYear getStartYear() { + return startYear; + } + + public void setStartYear(DYear startYear) { + this.startYear = startYear; + } + + public MinuteOfTheYear getStartTime() { + return startTime; + } + + public void setStartTime(MinuteOfTheYear startTime) { + this.startTime = startTime; + } + + public MinutesDuration getDuratonTime() { + return duratonTime; + } + + public void setDuratonTime(MinutesDuration duratonTime) { + this.duratonTime = duratonTime; + } + + public SignPrority getPriority() { + return priority; + } + + public void setPriority(SignPrority priority) { + this.priority = priority; + } + + public SSPindex getNotUsed1() { + return notUsed1; + } + + public void setNotUsed1(SSPindex notUsed1) { + this.notUsed1 = notUsed1; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegions extends Asn1SequenceOf { + SequenceOfRegions() { + super(GeographicalPath.class, 1L, 16L); + } + } + + public SequenceOfRegions getRegions() { + return regions; + } + + public void setRegions(SequenceOfRegions regions) { + this.regions = regions; + } + + public SSPindex getNotUsed2() { + return notUsed2; + } + + public void setNotUsed2(SSPindex notUsed2) { + this.notUsed2 = notUsed2; + } + + public SSPindex getNotUsed3() { + return notUsed3; + } + + public void setNotUsed3(SSPindex notUsed3) { + this.notUsed3 = notUsed3; + } + + @JsonInclude(Include.NON_NULL) + public static class ContentChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = AdvisoryDeserializer.class) + @JsonSerialize(using = AdvisorySerializer.class) + private ITIScodesAndText advisory; + @Asn1Property(tag = 1) + @JsonDeserialize(using = WorkZoneDeserializer.class) + @JsonSerialize(using = WorkZoneSerializer.class) + private WorkZone workZone; + @Asn1Property(tag = 2) + @JsonDeserialize(using = GenericSignDeserializer.class) + @JsonSerialize(using = GenericSignSerializer.class) + private GenericSignage genericSign; + @Asn1Property(tag = 3) + @JsonDeserialize(using = SpeedLimitDeserializer.class) + @JsonSerialize(using = SpeedLimitSerializer.class) + private SpeedLimit speedLimit; + @Asn1Property(tag = 4) + @JsonDeserialize(using = ExitServiceDeserializer.class) + @JsonSerialize(using = ExitServiceSerializer.class) + private ExitService exitService; + + ContentChoice() { + super(false); + } + + public ITIScodesAndText getAdvisory() { + return advisory; + } + + public void setAdvisory(ITIScodesAndText advisory) { + this.advisory = advisory; + } + + public WorkZone getWorkZone() { + return workZone; + } + + public void setWorkZone(WorkZone workZone) { + this.workZone = workZone; + } + + public GenericSignage getGenericSign() { + return genericSign; + } + + public void setGenericSign(GenericSignage genericSign) { + this.genericSign = genericSign; + } + + public SpeedLimit getSpeedLimit() { + return speedLimit; + } + + public void setSpeedLimit(SpeedLimit speedLimit) { + this.speedLimit = speedLimit; + } + + public ExitService getExitService() { + return exitService; + } + + public void setExitService(ExitService exitService) { + this.exitService = exitService; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ContentChoice getContent() { + return content; + } + + public void setContent(ContentChoice content) { + this.content = content; + } + + public URL_Short getUrl() { + return url; + } + + public void setUrl(URL_Short url) { + this.url = url; + } + + TravelerDataFrame() { + super(true); + } + + public static class AdvisoryDeserializer extends NestedSequenceOfDeserializer { + public AdvisoryDeserializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class AdvisorySerializer extends NestedSequenceOfSerializer { + public AdvisorySerializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class WorkZoneDeserializer extends NestedSequenceOfDeserializer { + public WorkZoneDeserializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class WorkZoneSerializer extends NestedSequenceOfSerializer { + public WorkZoneSerializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class GenericSignDeserializer extends NestedSequenceOfDeserializer { + public GenericSignDeserializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class GenericSignSerializer extends NestedSequenceOfSerializer { + public GenericSignSerializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class SpeedLimitDeserializer extends NestedSequenceOfDeserializer { + public SpeedLimitDeserializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class SpeedLimitSerializer extends NestedSequenceOfSerializer { + public SpeedLimitSerializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class ExitServiceDeserializer extends NestedSequenceOfDeserializer { + public ExitServiceDeserializer() { + super(ExitService.class, "SEQUENCE"); + } + } + + public static class ExitServiceSerializer extends NestedSequenceOfSerializer { + public ExitServiceSerializer() { + super(ExitService.class, "SEQUENCE"); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java new file mode 100644 index 000000000..4b5e810be --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class TravelerDataFrameList extends Asn1SequenceOf { + + TravelerDataFrameList() { + super(TravelerDataFrame.class, 1L, 8L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java new file mode 100644 index 000000000..206999c8c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonSerialize(using = TravelerInfoTypeSerializer.class) +@JsonDeserialize(using = TravelerInfoTypeDeserializer.class) +public enum TravelerInfoType implements Asn1Enumerated { + unknown(0, "unknown"), advisory(1, "advisory"), roadSignage(2, "roadSignage"), commercialSignage(3, + "commercialSignage"); + + private final int index; + private final String name; + + public int getIndex() { + return index; + } + + public String getName() { + return name; + } + + public boolean hasExtensionMarker() { + return false; + } + + private TravelerInfoType(int index, String name) { + this.index = index; + this.name = name; + } + + public int maxIndex() { + return 3; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java new file mode 100644 index 000000000..7062d0455 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java @@ -0,0 +1,32 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class TravelerInfoTypeDeserializer extends EnumeratedDeserializer { + + TravelerInfoTypeDeserializer() { + super(TravelerInfoType.class); + } + + @Override + protected TravelerInfoType[] listEnumValues() { + return TravelerInfoType.values(); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java new file mode 100644 index 000000000..f17d6c568 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class TravelerInfoTypeSerializer extends EnumeratedSerializer { + + TravelerInfoTypeSerializer() { + super(TravelerInfoType.class); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java new file mode 100644 index 000000000..f83b11b43 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java @@ -0,0 +1,111 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +//import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TravelerInformation extends Asn1Object { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = MsgCount.MsgCountDeserializer.class) + private MsgCount msgCnt; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + private MinuteOfTheYear timeStamp; + @Asn1Property(tag = 2, optional = true) + private UniqueMSGID packetID; + @Asn1Property(tag = 3, optional = true) + private URL_Base urlB; + @Asn1Property(tag = 4) + @JacksonXmlElementWrapper(localName = "dataFrames") + @JacksonXmlProperty(localName = "TravelerDataFrame") + private TravelerDataFrameList dataFrames; + @Asn1Property(tag = 5, optional = true) + private SequenceOfRegional regional; + + public MsgCount getMsgCnt() { + return msgCnt; + } + + public void setMsgCnt(MsgCount msgCnt) { + this.msgCnt = msgCnt; + } + + public MinuteOfTheYear getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(MinuteOfTheYear timeStamp) { + this.timeStamp = timeStamp; + } + + public UniqueMSGID getPacketID() { + return packetID; + } + + public void setPacketID(UniqueMSGID packetID) { + this.packetID = packetID; + } + + public URL_Base getUrlB() { + return urlB; + } + + public void setUrlB(URL_Base urlB) { + this.urlB = urlB; + } + + public TravelerDataFrameList getDataFrames() { + return dataFrames; + } + + public void setDataFrames(TravelerDataFrameList dataFrames) { + this.dataFrames = dataFrames; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + // TravelerInformation() { + // super(true); + // } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java new file mode 100644 index 000000000..a93a91c93 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java @@ -0,0 +1,34 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.IA5String; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class URL_Base extends IA5String { + + public URL_Base() { + super(1, 45); + } + + @JsonCreator + public URL_Base(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java new file mode 100644 index 000000000..f95536afa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java @@ -0,0 +1,34 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.IA5String; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class URL_Short extends IA5String { + + public URL_Short() { + super(1, 15); + } + + @JsonCreator + public URL_Short(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java new file mode 100644 index 000000000..a700e956b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java @@ -0,0 +1,49 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class UniqueMSGID extends Asn1OctetString { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } + + public UniqueMSGID() { + super(9, 9); + } + + @JsonCreator + public UniqueMSGID(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java new file mode 100644 index 000000000..b6d3bc1c1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java @@ -0,0 +1,111 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ValidRegion extends Asn1Sequence { + + @Asn1Property(tag = 0) + private HeadingSlice direction; + @Asn1Property(tag = 1, optional = true) + private Extent extent; + @Asn1Property(tag = 2) + private AreaChoice area; + + public HeadingSlice getDirection() { + return direction; + } + + public void setDirection(HeadingSlice direction) { + this.direction = direction; + } + + public Extent getExtent() { + return extent; + } + + public void setExtent(Extent extent) { + this.extent = extent; + } + + @JsonInclude(Include.NON_NULL) + public static class AreaChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private ShapePointSet shapePointSet; + @Asn1Property(tag = 1) + private Circle circle; + @Asn1Property(tag = 2) + private RegionPointSet regionPointSet; + + AreaChoice() { + super(false); + } + + public ShapePointSet getShapePointSet() { + return shapePointSet; + } + + public void setShapePointSet(ShapePointSet shapePointSet) { + this.shapePointSet = shapePointSet; + } + + public Circle getCircle() { + return circle; + } + + public void setCircle(Circle circle) { + this.circle = circle; + } + + public RegionPointSet getRegionPointSet() { + return regionPointSet; + } + + public void setRegionPointSet(RegionPointSet regionPointSet) { + this.regionPointSet = regionPointSet; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public AreaChoice getArea() { + return area; + } + + public void setArea(AreaChoice area) { + this.area = area; + } + + ValidRegion() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java new file mode 100644 index 000000000..959be197f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Velocity extends Asn1Integer { + + public Velocity() { + super(0L, 8191L); + } + + @JsonCreator + public Velocity(long value) { + this(); + this.value = value; + } + + public static class VelocityDeserializer extends IntegerDeserializer { + public VelocityDeserializer() { + super(Velocity.class); + } + + @Override + protected Velocity construct() { + return new Velocity(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java new file mode 100644 index 000000000..78268ac2b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class WorkZone extends Asn1SequenceOf { + + WorkZone() { + super(WorkZoneSequence.class, 1L, 16L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java new file mode 100644 index 000000000..4d7733b38 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java @@ -0,0 +1,84 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class WorkZoneSequence extends Asn1Sequence { + + @Asn1Property(tag = 0) + private ItemChoice item; + + @JsonInclude(Include.NON_NULL) + public static class ItemChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + private ITIScodes itis; + @Asn1Property(tag = 1) + private ITIStextPhrase text; + + ItemChoice() { + super(false); + } + + public ITIScodes getItis() { + return itis; + } + + public void setItis(ITIScodes itis) { + this.itis = itis; + } + + public ITIStextPhrase getText() { + return text; + } + + public void setText(ITIStextPhrase text) { + this.text = text; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ItemChoice getItem() { + return item; + } + + public void setItem(ItemChoice item) { + this.item = item; + } + + WorkZoneSequence() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java new file mode 100644 index 000000000..a970950fc --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class Zoom extends Asn1Integer { + + public Zoom() { + super(0L, 15L); + } + + @JsonCreator + public Zoom(long value) { + this(); + this.value = value; + } + + public static class ZoomDeserializer extends IntegerDeserializer { + public ZoomDeserializer() { + super(Zoom.class); + } + + @Override + protected Zoom construct() { + return new Zoom(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java new file mode 100644 index 000000000..5b6079e51 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java @@ -0,0 +1,46 @@ +package us.dot.its.jpo.ode.plugin.j2735.ITIS; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class ITIScodes extends Asn1Integer { + + public ITIScodes() { + super(0L, 65535L); + } + + @JsonCreator + public ITIScodes(long value) { + this(); + this.value = value; + } + + public static class ITIScodesDeserializer extends IntegerDeserializer { + public ITIScodesDeserializer() { + super(ITIScodes.class); + } + + @Override + protected ITIScodes construct() { + return new ITIScodes(); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java new file mode 100644 index 000000000..18c2874b2 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.ITIS; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +public class ITIScodesAndText extends Asn1SequenceOf { + + ITIScodesAndText() { + super(ITIScodesAndTextSequence.class, 1L, 100L); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java new file mode 100644 index 000000000..5a8b4102f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java @@ -0,0 +1,83 @@ +package us.dot.its.jpo.ode.plugin.j2735.ITIS; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ITIScodesAndTextSequence extends Asn1Sequence { + + @Asn1Property(tag = 0) + private ItemChoice item; + + @JsonInclude(Include.NON_NULL) + public static class ItemChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + private ITIScodes itis; + @Asn1Property(tag = 1) + private ITIStext text; + + ItemChoice() { + super(false); + } + + public ITIScodes getItis() { + return itis; + } + + public void setItis(ITIScodes itis) { + this.itis = itis; + } + + public ITIStext getText() { + return text; + } + + public void setText(ITIStext text) { + this.text = text; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ItemChoice getItem() { + return item; + } + + public void setItem(ItemChoice item) { + this.item = item; + } + + ITIScodesAndTextSequence() { + super(false); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java new file mode 100644 index 000000000..f517967ae --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java @@ -0,0 +1,34 @@ +package us.dot.its.jpo.ode.plugin.j2735.ITIS; + +import us.dot.its.jpo.ode.plugin.types.IA5String; +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +public class ITIStext extends IA5String { + + public ITIStext() { + super(1, 500); + } + + @JsonCreator + public ITIStext(String value) { + this(); + this.value = value; + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java new file mode 100644 index 000000000..f979efaa4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_ComputedLane extends RegionalExtension { + + public Reg_ComputedLane(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java new file mode 100644 index 000000000..c31cb1a3d --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_GeographicalPath extends RegionalExtension { + + public Reg_GeographicalPath(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java new file mode 100644 index 000000000..7e1c121f6 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_GeometricProjection extends RegionalExtension { + + public Reg_GeometricProjection(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java new file mode 100644 index 000000000..484f60051 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") +@JsonSubTypes({ + @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, name = "2")}) +@Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { + @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, intId = 2)}) +abstract public class Reg_LaneDataAttribute extends RegionalExtension { + + public Reg_LaneDataAttribute(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java new file mode 100644 index 000000000..e3cb75c81 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_NodeAttributeSetLL extends RegionalExtension { + + public Reg_NodeAttributeSetLL(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java new file mode 100644 index 000000000..bcc1df192 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_NodeAttributeSetXY extends RegionalExtension { + + public Reg_NodeAttributeSetXY(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java new file mode 100644 index 000000000..ea683e0ee --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_NodeOffsetPointLL extends RegionalExtension { + + public Reg_NodeOffsetPointLL(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java new file mode 100644 index 000000000..2ac717f5e --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") +@JsonSubTypes({ + @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, name = "2")}) +@Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { + @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, intId = 2)}) +abstract public class Reg_NodeOffsetPointXY extends RegionalExtension { + + public Reg_NodeOffsetPointXY(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java new file mode 100644 index 000000000..59e04379c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java @@ -0,0 +1,42 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") +@JsonSubTypes({@JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D.class, name = "2"), + @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D.class, name = "3")}) +@Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { + @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D.class, intId = 2), + @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D.class, intId = 3)}) +abstract public class Reg_Position3D extends RegionalExtension { + + public Reg_Position3D(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java new file mode 100644 index 000000000..79478a6ca --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java @@ -0,0 +1,30 @@ +package us.dot.its.jpo.ode.plugin.j2735.REGION; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; + +/** + * + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +abstract public class Reg_TravelerInformation extends RegionalExtension { + + public Reg_TravelerInformation(int id, String name) { + super(id, name); + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java index fa981e56c..b6a320bff 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListXYBuilder.java @@ -36,21 +36,9 @@ public static J2735NodeListXY genericNodeListXY(JsonNode nodeListNode) { nodeList.setNodes(nxyList.toArray(new J2735NodeXY[0])); } } else if (nodeListNode.get("computed") != null) { - JsonNode computedLane = nodeListNode.get("computed").get("ComputedLane"); + JsonNode computedLane = nodeListNode.get("computed"); if (computedLane != null) { - List clList = new ArrayList<>(); - - if (computedLane.isArray()) { - Iterator elements = computedLane.elements(); - - while (elements.hasNext()) { - clList.add(ComputedLaneBuilder.genericComputedLane(elements.next())); - } - } else { - clList.add(ComputedLaneBuilder.genericComputedLane(computedLane)); - } - - nodeList.setComputed(clList.toArray(new J2735ComputedLane[0])); + nodeList.setComputed(ComputedLaneBuilder.genericComputedLane(computedLane)); } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java new file mode 100644 index 000000000..b7aeeb0e1 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java @@ -0,0 +1,39 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +import java.io.IOException; + +/** + * Deserialize an ASN.1 Bitstring from XER or JER + * @param The bitstring type + * @author Ivan Yourshaw + */ +public abstract class BitStringDeserializer extends StdDeserializer { + + protected abstract T construct(); + + protected BitStringDeserializer(Class valueClass) { + super(valueClass); + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + String str = jsonParser.getText(); + T bitstring = construct(); + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML: binary + bitstring.fromBinaryString(str); + } else { + // JSON: hex + bitstring.fromHexString(str); + } + return bitstring; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java new file mode 100644 index 000000000..1f4616964 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java @@ -0,0 +1,31 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; + +import java.io.IOException; + +/** + * Serializer for ASN.1 Bitstring types to XER or JER + * @author Ivan Yourshaw + */ +public class BitstringSerializer extends StdSerializer { + + protected BitstringSerializer() { + super(Asn1Bitstring.class); + } + + @Override + public void serialize(Asn1Bitstring asn1Bitstring, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // XER serializes enums as binary + jsonGenerator.writeString(asn1Bitstring.binaryString()); + } else { + // JER serializes enums as hex + jsonGenerator.writeString(asn1Bitstring.hexString()); + } + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java new file mode 100644 index 000000000..05e37dbb0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java @@ -0,0 +1,45 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +import java.io.IOException; + +@SuppressWarnings({"unchecked", "rawtypes"}) +public class BooleanDeserializer extends StdDeserializer { + + protected Asn1Boolean construct() { + return new Asn1Boolean(); + } + + public BooleanDeserializer() { + super(Asn1Boolean.class); + } + + protected BooleanDeserializer(Class valueType) { + super(Asn1Boolean.class); + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + Asn1Boolean result = construct(); + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML: unwrap empty element + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + var iterator = node.fieldNames(); + if (iterator.hasNext()) { + String str = node.fieldNames().next(); + result.setValue(Boolean.parseBoolean(str)); + } + } else { + // JSON + result.setValue(jsonParser.getBooleanValue()); + } + return (T)result; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java new file mode 100644 index 000000000..35fe77d62 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java @@ -0,0 +1,29 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; + +import java.io.IOException; + +public class BooleanSerializer extends StdSerializer { + + protected BooleanSerializer() { + super(Asn1Boolean.class); + } + + @Override + public void serialize(Asn1Boolean asn1Boolean, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // XER uses and for booleans + jsonGenerator.writeStartObject(); + jsonGenerator.writeRaw(String.format("<%s/>", asn1Boolean.getValue())); + jsonGenerator.writeEndObject(); + } else { + // JER + jsonGenerator.writeBoolean(asn1Boolean.getValue()); + } + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java new file mode 100644 index 000000000..7d34858b4 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java @@ -0,0 +1,20 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1CharacterString; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; + +public class CharacterStringSerializer extends StdSerializer { + + protected CharacterStringSerializer() { + super(Asn1CharacterString.class); + } + + @Override + public void serialize(Asn1CharacterString asn1CharacterString, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(asn1CharacterString.getValue()); + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java new file mode 100644 index 000000000..524feb68c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java @@ -0,0 +1,48 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +import java.io.IOException; +import java.util.Objects; + +public abstract class EnumeratedDeserializer & Asn1Enumerated> extends StdDeserializer { + + protected abstract T[] listEnumValues(); + + protected EnumeratedDeserializer(Class valueClass) { + super(valueClass); + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + String name = null; + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML + // The enum in BASIC-XER is an empty element, so Jackson thinks it's an object with a key + // of that name with no value + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + var iterator = node.fieldNames(); + if (iterator.hasNext()) { + name = node.fieldNames().next(); + } + } else { + // JSON + // Behaves normally: The enum name is the text + name = jsonParser.getText(); + } + for (T enumValue : listEnumValues()) { + if (Objects.equals(enumValue.getName(), name)) { + return enumValue; + } + } + + + return null; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java new file mode 100644 index 000000000..013cd53d5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; + +import java.io.IOException; + +/** + * Base class for ENUMERATED value serializers to produce both XER and JER + * @param The ENUMERATED type + * TODO: this doesn't need to be generic + * @author Ivan Yourshaw + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public class EnumeratedSerializer extends StdSerializer { + + + protected EnumeratedSerializer(Class t) { + super(t); + } + + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + jsonGenerator.writeStartObject(); + + // + // BASIC-XER's weird way of writing enums. + // + // Ref. ITU-T X.693 (02/2021) Sec. 8.3.7 which says: + // + // The "XMLEnumeratedValue" specified in Rec. ITU-T X.680 | ISO/IEC 8824-1, 20.8, shall only be + // "EmptyElementEnumerated" + // + // and ITU-T X.680 (02/2021) Sec. 20.8 which says: + // + // EmptyElementEnumerated ::= "<" & identifier "/>" + // + jsonGenerator.writeRaw(String.format("<%s/>", t.getName())); + + jsonGenerator.writeEndObject(); + } else { + // + // JER: Just write the enum value as a string like a normal person. + // Does not handle TEXT encoding instructions per X.697 sec 22.2 + // + jsonGenerator.writeString(t.getName()); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java new file mode 100644 index 000000000..4e044314a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java @@ -0,0 +1,47 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.NumericNode; +import com.fasterxml.jackson.databind.node.TextNode; +import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; + +import java.io.IOException; + +public abstract class IntegerDeserializer extends StdDeserializer { + + protected final Class thisClass; + protected abstract T construct(); + + protected IntegerDeserializer(Class vc) { + super(vc); + this.thisClass = vc; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + result = construct(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + System.out.printf("type: %s%n", thisClass.getName()); + System.out.printf("node: %s%n", node); + System.out.printf("node type: %s%n", node.getClass().getName()); + if (node instanceof NumericNode numNode) { + result.setValue(numNode.longValue()); + } else if (node instanceof TextNode textNode) { + // Sometimes happens, since XML values are ambiguous between text and numbers + String textValue = textNode.textValue(); + long value = Long.parseLong(textValue); + result.setValue(value); + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); + } + return result; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java new file mode 100644 index 000000000..3e97059e0 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java @@ -0,0 +1,60 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; + +import java.io.IOException; + +/** + * Serializer for nested, anonymous SEQUENCE-OF types. Handles XER's way of wrapping these. + * @param The Sequence Of type + * @author Ivan Yourshaw + */ +public class NestedSequenceOfDeserializer> extends StdDeserializer { + + protected final Class thisClass; + protected final String wrapped; + + protected NestedSequenceOfDeserializer(Class vc, String wrapped) { + super(vc); + this.thisClass = vc; + this.wrapped = wrapped; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + // For XML, we need to remove the wrapper and distinguish between single items and arrays + XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + + if (node instanceof ObjectNode objectNode) { + JsonNode unwrapped = objectNode.findValue(wrapped); + if (unwrapped instanceof ObjectNode unwrappedObject) { + + // Single item not identified as array, so put it in an array + ArrayNode arrayNode = xmlMapper.createArrayNode(); + arrayNode.add(unwrappedObject); + result = xmlMapper.convertValue(arrayNode, thisClass); + + } else if (unwrapped instanceof ArrayNode arrayNode) { + + result = xmlMapper.convertValue(arrayNode, thisClass); + } + } + }else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); + } + return result; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java new file mode 100644 index 000000000..4ca05d752 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java @@ -0,0 +1,55 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; + +import javax.xml.namespace.QName; +import java.io.IOException; + +/** + * Serializer for nested, anonymous SEQUENCT-OF types + * @param The Sequence-of type + * @author Ivan Yourshaw + */ +public class NestedSequenceOfSerializer> extends StdSerializer { + + protected final QName wrapped; + + protected NestedSequenceOfSerializer(Class t, String wrapped) { + super(t); + this.wrapped = new QName(wrapped); + } + + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // Wrapped XER + var xmlGen = (ToXmlGenerator)jsonGenerator; + for (var item : t) { + + xmlGen.writeRaw(String.format("<%s>", wrapped)); + var mapper = SerializationUtil.xmlMapper(); + String itemXml = mapper.writeValueAsString(item); + + // Horrible hack to write the item value without being wrapped by the class name. + // Probably a better way exists, but this works. + String itemClassName = item.getClass().getSimpleName(); + String startElement = String.format("<%s>", itemClassName); + String endElement = String.format("", itemClassName); + String strippedXml = itemXml.replace(startElement, "").replace(endElement, ""); + + xmlGen.writeRaw(strippedXml); + + xmlGen.writeRaw(String.format("", wrapped)); + } + + } else { + // Pass through JER + jsonGenerator.writeObject(t); + } + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java new file mode 100644 index 000000000..28f93a108 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; + +import java.io.IOException; + +/** + * See description in {@link OpenTypeSerializer} + * @author Ivan Yourshaw + */ +public abstract class OpenTypeDeserializer extends StdDeserializer { + + protected final Class thisClass; + protected final String wrapped; + + protected OpenTypeDeserializer(Class vc, String wrapped) { + super(vc); + thisClass = vc; + this.wrapped = wrapped; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + if (node instanceof ObjectNode objectNode) { + JsonNode unwrapped = objectNode.findValue(wrapped); + + // HACK: serialization annotations are ignored here. + // ideally we would like to just unwrap the original literal xml and pass it through + // but Jackson's XML parser insists on converting everything to JSON, so the original XML is + // not preserved. Specifically, empty elements like are expanded to , + // but the boolean and enumerated deserializers can still handle this. + String unwrappedXml = xmlMapper.writeValueAsString(unwrapped); + + result = xmlMapper.readValue(unwrappedXml, thisClass); + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); + } + return result; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java new file mode 100644 index 000000000..5a2d0bfa6 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java @@ -0,0 +1,76 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; + +import javax.xml.namespace.QName; +import java.io.IOException; + +/** + * Serializer for ASN.1 "open types" which are fields without a specific type, + * for dealing with parameterized fields with value sets of different types that + * can be plugged in. In this Java implementation these are represented by type parameters + * in abstract types. + * + *

For example, the contents of the "value" field in a J2735 MessageFrame. + * + *

XER wraps open types with the type name like: + *

{@code
+ *
+ *     
+ *         19
+ *         
+ *             
+ *                 ...
+ *             
+ *         
+ *     
+ *
+ *  }
+ *

See XMLOpenTypeFieldValue: ITU-T Rec. X.681 (02/2021) Section 14.6. + * + *

JER does not wrap them: + *

{@code
+ *
+ *     {
+ *         "messageId": 19,
+ *         "value": {
+ *             ...
+ *         }
+ *     }
+ *
+ * }
+ *

See "Encoding of open type values", ITU-T Rec X.697 (02/2021), Sec 41. + * + * @author Ivan Yourshaw + */ +public abstract class OpenTypeSerializer extends StdSerializer { + + protected final QName wrapper; + protected final QName wrapped; + + protected OpenTypeSerializer(Class t, String wrapper, String wrapped) { + super(t); + this.wrapper = new QName(wrapper); + this.wrapped = new QName(wrapped); + } + + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // Wrapped XER + var xmlGen = (ToXmlGenerator)jsonGenerator; + xmlGen.startWrappedValue(wrapper, wrapped); + xmlGen.writeObject(t); + xmlGen.finishWrappedValue(wrapper, wrapped); + } else { + // Pass through JER + jsonGenerator.writeObject(t); + } + + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java new file mode 100644 index 000000000..72dea516c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java @@ -0,0 +1,68 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.io.IOException; + +import static us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType.INTEGER; + +/** + * Deserialize a parameterized SEQUENCE type. + * Determines the subtype to deserialize to using the {@link Asn1ParameterizedTypes} annotation that + * must be present. + * + * @param The Sequence Type + * + * @author Ivan Yourshaw + */ +@SuppressWarnings({"unchecked", "rawtypes"}) +public abstract class ParameterizedTypeDeserializer extends StdDeserializer { + + protected final Class thisClass; + + protected ParameterizedTypeDeserializer(Class vc) { + super(vc); + thisClass = vc; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + final var typeAnnot = thisClass.getAnnotation(Asn1ParameterizedTypes.class); + if (typeAnnot == null) { + throw new RuntimeException("Missing Asn1ParameterizedTypes annotation."); + } + final String idPropName = typeAnnot.idProperty(); + final Asn1ParameterizedTypes.IdType idType = typeAnnot.idType(); + final Asn1ParameterizedTypes.Type[] types = typeAnnot.value(); + if (types == null || types.length == 0) { + throw new RuntimeException("No Types are defined in the Asn1ParameterizedTypes annotation."); + } + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + if (node instanceof ObjectNode objectNode) { + JsonNode idPropNode = objectNode.findValue(idPropName); + final Object id = (idType == INTEGER) ? idPropNode.asInt() : idPropNode.asText(); + Class subType = getSubtypeForId(id, idType, types); + return (T)jsonParser.getCodec().readValue(jsonParser, subType); + } else { + throw new RuntimeException("Not instance of object"); + } + } + + private Class getSubtypeForId(final Object id, Asn1ParameterizedTypes.IdType idType, Asn1ParameterizedTypes.Type[] types) { + for (var theType : types) { + Object idValue = (idType == INTEGER) ? theType.intId() : theType.stringId(); + if (id.equals(idValue)) { + return theType.value(); + } + } + throw new RuntimeException(String.format("Id %s not found in list of types", id)); + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java new file mode 100644 index 000000000..e99b69f28 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java @@ -0,0 +1,53 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; + +import java.io.IOException; +import java.util.Objects; + +public abstract class SequenceOfEnumeratedDeserializer & Asn1Enumerated, T extends Asn1SequenceOf> + extends StdDeserializer { + + protected final Class thisClass; + protected final Class enumClass; + protected abstract S[] listEnumValues(); + protected abstract T construct(); + + protected SequenceOfEnumeratedDeserializer(Class sequenceOfEnumType, Class enumType) { + super(sequenceOfEnumType); + this.thisClass = sequenceOfEnumType; + this.enumClass = enumType; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + // Unwrapped enum items + result = construct(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + System.out.printf("type: %s%n", thisClass.getName()); + System.out.printf("node: %s%n", node); + var fieldNameIterator = node.fieldNames(); + while (fieldNameIterator.hasNext()) { + String name = fieldNameIterator.next(); + System.out.printf("enum value: %s%n", name); + for (S enumValue : listEnumValues()) { + if (Objects.equals(enumValue.getName(), name)) { + result.add(enumValue); + } + } + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); + } + return result; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java new file mode 100644 index 000000000..8b7cb9f5a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java @@ -0,0 +1,18 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; + +public class SerializationUtil { + + private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final XmlMapper xmlMapper = new XmlMapper(); + + public static ObjectMapper jsonMapper() { + return jsonMapper; + } + + public static XmlMapper xmlMapper() { + return xmlMapper; + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/package-info.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/package-info.java new file mode 100644 index 000000000..ba7a7c48b --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/package-info.java @@ -0,0 +1,4 @@ +/** + * Jackson serializers and deserializers for XER and JER. + */ +package us.dot.its.jpo.ode.plugin.serialization; \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java new file mode 100644 index 000000000..d7328bfcc --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -0,0 +1,113 @@ +package us.dot.its.jpo.ode.plugin.types; + +import us.dot.its.jpo.ode.plugin.serialization.BitstringSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.util.BitSet; +import java.util.HexFormat; + +import static us.dot.its.jpo.ode.plugin.utils.BitUtils.reverseBits; + +@JsonSerialize(using = BitstringSerializer.class) +public abstract class Asn1Bitstring implements Asn1Type { + + final BitSet bits; + final int size; + final boolean hasExtensionMarker; + final String[] names; + + public Asn1Bitstring(int size, boolean hasExtensionMarker, String[] names) { + this.size = size; + this.hasExtensionMarker = hasExtensionMarker; + this.bits = new BitSet(size); + this.names = names; + } + + public int size() { + return size; + } + + public boolean hasExtensionMarker() { + return hasExtensionMarker; + } + + public boolean get(int bitIndex) { + return bits.get(bitIndex); + } + + public void set(int bitIndex, boolean value) { + bits.set(bitIndex, value); + } + + public String binaryString() { + char[] chars = new char[size]; + for (int i = 0; i < size; i++) { + chars[i] = get(i) ? '1' : '0'; + } + return new String(chars); + } + + public String hexString() { + HexFormat hex = HexFormat.of(); + return hex.formatHex(reverseBits(bits.toByteArray())); + } + + public void fromBinaryString(String str) { + if (str == null) { + bits.clear(); + return; + } + char[] chars = str.toCharArray(); + if (chars.length < size) { + throw new IllegalArgumentException("Not enough characters in string " + str); + } + for (int i = 0; i < size; i++) { + char c = chars[i]; + set(i, c == '1'); + } + } + + public void fromHexString(String str) { + System.out.println(str); + if (str == null) { + bits.clear(); + return; + } + HexFormat hex = HexFormat.of(); + byte[] bytes = reverseBits(hex.parseHex(str)); + System.out.println(bytes.length); + BitSet newBits = BitSet.valueOf(bytes); + System.out.println(newBits); + + bits.clear(); + bits.or(newBits); + System.out.println(binaryString()); + } + + public String name(int index) { + if (index < 0 || index >= size()) { + throw new IllegalArgumentException(String.format("Index %s out of range %s-%s", index, 0, size())); + } + return names[index]; + } + + @Override + public int hashCode() { + return bits.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (obj instanceof Asn1Bitstring bitstring) { + return bits.equals(bitstring.bits); + } else { + return false; + } + } + + @Override + public String toString() { + return binaryString(); + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java new file mode 100644 index 000000000..f20dd969a --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java @@ -0,0 +1,55 @@ +package us.dot.its.jpo.ode.plugin.types; + +import us.dot.its.jpo.ode.plugin.serialization.BooleanDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.BooleanSerializer; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +import java.util.Objects; + + + +@JsonSerialize(using = BooleanSerializer.class) +@JsonDeserialize(using = BooleanDeserializer.class) +public class Asn1Boolean implements Asn1Type { + + public Asn1Boolean() {} + + @JsonCreator + public Asn1Boolean(boolean value) { + this.value = value; + } + + private boolean value; + + @JsonValue + public boolean getValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Asn1Boolean that = (Asn1Boolean) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @Override + public String toString() { + return Boolean.toString(value); + } + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java new file mode 100644 index 000000000..095a00cc8 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.types; + +import com.fasterxml.jackson.annotation.JsonValue; + +//@JsonSerialize(using = CharacterStringSerializer.class) +public abstract class Asn1CharacterString implements Asn1Type { + + protected final int minLength; + protected final int maxLength; + protected String value; + + public Asn1CharacterString(int minLength, int maxLength) { + this.minLength = minLength; + this.maxLength = maxLength; + } + + @JsonValue + public String getValue() { + return value; + } + + public void setValue(String value) { + if (!validate(value)) { + throw new IllegalArgumentException( + String.format("String '%s' has invalid length. Must be between %d and %s", + value, minLength, maxLength)); + } + this.value = value; + } + + protected boolean validate(String aValue) { + if (aValue == null) return true; + return aValue.length() >= minLength && aValue.length() <= maxLength; + } + + @Override + public String toString() { + return value; + } + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java new file mode 100644 index 000000000..edb753de9 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java @@ -0,0 +1,58 @@ +package us.dot.its.jpo.ode.plugin.types; + +import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.List; +import java.util.Optional; + +public abstract class Asn1Choice implements Asn1Type { + + final boolean hasExtensionMarker; + + public Asn1Choice(boolean hasExtensionMarker) { + this.hasExtensionMarker = hasExtensionMarker; + } + + /** + * Validates if one and only one option is selected for the choice + */ + protected boolean isValid() { + var types = listTypes(); + long numChosen = types.stream().filter(Optional::isPresent).count(); + return numChosen == 1; + } + + /** + * Ref ITU-T X.691 (02/2021) Section 23 + * @return the index of the chosen alternative + */ + protected int chosenIndex() { + List> types = listTypes(); + for (int i = 0; i < types.size(); i++) { + if (types.get(i).isPresent()) return i; + } + return -1; + } + + protected int maxIndex() { + return listTypes().size() - 1; + } + + abstract protected List> listTypes(); + + + + + @Override + public String toString() { + ObjectMapper mapper = SerializationUtil.jsonMapper(); + try { + return mapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + System.err.println(e.getMessage()); + return ""; + } + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java new file mode 100644 index 000000000..6257707b3 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java @@ -0,0 +1,10 @@ +package us.dot.its.jpo.ode.plugin.types; + +public interface Asn1Enumerated extends Asn1Type { + int getIndex(); + String getName(); + boolean hasExtensionMarker(); + int maxIndex(); + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java new file mode 100644 index 000000000..2ee29d0fc --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java @@ -0,0 +1,5 @@ +//package asn2pojo.runtime.types; +// +//public record Asn1Field(String name, Asn1Type value, boolean optional, int tag) { +// +//} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java new file mode 100644 index 000000000..7dc62b002 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java @@ -0,0 +1,68 @@ +package us.dot.its.jpo.ode.plugin.types; + +import com.fasterxml.jackson.annotation.JsonValue; + +import java.util.Objects; + +/** + * A constrained integer type with lower bound and upper bound. + * Unconstrained integer types and extensibility markers in integer constraints are not supported. + */ +//@JsonSerialize(using = IntegerSerializer.class) +public class Asn1Integer implements Asn1Type, Comparable { + + protected long value; + final long lowerBound; + final long upperBound; + + public Asn1Integer(long lowerBound, long upperBound) { + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + @JsonValue + public long getValue() { + return value; + } + + public void setValue(long value) { + this.value = value; + } + + public int intValue() { + return (int)value; + } + + @Override + public int compareTo(Asn1Integer other) { + if (other == null) return -1; + return Long.compare(value, other.value); + } + + public long getLowerBound() { + return lowerBound; + } + + public long getUpperBound() { + return upperBound; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Asn1Integer that = (Asn1Integer) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @Override + public String toString() { + return Long.toString(value); + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java new file mode 100644 index 000000000..14081d391 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java @@ -0,0 +1,11 @@ +package us.dot.its.jpo.ode.plugin.types; + +public class Asn1OctetString extends Asn1CharacterString { + + public Asn1OctetString(int minLength, int maxLength) { + super(minLength, maxLength); + } + + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java new file mode 100644 index 000000000..9a81fceda --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java @@ -0,0 +1,31 @@ +package us.dot.its.jpo.ode.plugin.types; + +import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public abstract class Asn1Sequence implements Asn1Type { + + final boolean extensionMarker; + + public Asn1Sequence(boolean hasExtensionMarker) { + this.extensionMarker = hasExtensionMarker; + } + + public boolean hasExtensionMarker() { + return extensionMarker; + } + + + + @Override + public String toString() { + ObjectMapper mapper = SerializationUtil.jsonMapper(); + try { + return mapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + System.err.println(e.getMessage()); + return ""; + } + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java new file mode 100644 index 000000000..703fa802f --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java @@ -0,0 +1,41 @@ +package us.dot.its.jpo.ode.plugin.types; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +import java.util.ArrayList; + + +public abstract class Asn1SequenceOf + extends ArrayList + implements Asn1Type { + + final Class itemClass; + final long sizeLowerBound; + final long sizeUpperBound; + + public Asn1SequenceOf(Class itemClass, long sizeLowerBound, long sizeUpperBound) { + this.itemClass = itemClass; + this.sizeLowerBound = sizeLowerBound; + this.sizeUpperBound = sizeUpperBound; + } + + @JsonIgnore + public Class getItemClass() { + return itemClass; + } + + @JsonIgnore + public long getSizeLowerBound() { + return sizeLowerBound; + } + + @JsonIgnore + public long getSizeUpperBound() { + return sizeUpperBound; + } + + @SuppressWarnings("unchecked") + public boolean add(Asn1Type item) { + return super.add((T)item); + } +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Type.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Type.java new file mode 100644 index 000000000..55009634c --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Type.java @@ -0,0 +1,8 @@ +package us.dot.its.jpo.ode.plugin.types; + +/** + * Interface implemented by all ASN.1 type classes. + */ +public interface Asn1Type { + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java new file mode 100644 index 000000000..54a4d3834 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java @@ -0,0 +1,15 @@ +package us.dot.its.jpo.ode.plugin.types; + +/** + * Character range = 0..127, UPER encoded with 7 bits per character + * Ref: ITU-T X.691 (02/2021) Section 30 + */ +public class IA5String extends Asn1CharacterString { + + + public IA5String(int minLength, int maxLength) { + super(minLength, maxLength); + } + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java new file mode 100644 index 000000000..101408f14 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java @@ -0,0 +1,9 @@ +package us.dot.its.jpo.ode.plugin.types; + +/** + * Placeholder for unknown types in the generated source. + * If classes of this type exist, it means the ASN.1 specification has an unsupported feature. + * @author Ivan Yourshaw + */ +public class UnknownType implements Asn1Type { +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/package-info.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/package-info.java new file mode 100644 index 000000000..098180aaa --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/package-info.java @@ -0,0 +1,4 @@ +/** + * Base classes and interfaces for ASN.1 types. + */ +package us.dot.its.jpo.ode.plugin.types; \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java new file mode 100644 index 000000000..901238fe3 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java @@ -0,0 +1,22 @@ +package us.dot.its.jpo.ode.plugin.utils; + + +public class BitUtils { + + + public static byte reverseBits(final byte b) { + var reversedInt = Integer.reverse((int)b << 24) & 0xff; + return (byte)reversedInt; + } + + public static byte[] reverseBits(final byte[] bytes) { + byte[] reversed = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + reversed[i] = reverseBits(bytes[i]); + } + return reversed; + } + + +} + diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index b1ec808f9..d3b58b204 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -14,7 +14,7 @@ import us.dot.its.jpo.ode.model.OdeTimPayload; import us.dot.its.jpo.ode.model.ReceivedMessageDetails; import us.dot.its.jpo.ode.model.RxSource; -import us.dot.its.jpo.ode.plugin.j2735.builders.TIMBuilder; +import us.dot.its.jpo.ode.plugin.j2735.DSRC.TravelerInformation; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; @@ -54,13 +54,16 @@ public static OdeTimData createOdeTimDataFromDecoded(String consumedData) throws metadata.setReceivedMessageDetails(null); } - OdeTimPayload payload = new OdeTimPayload(TIMBuilder.genericTim(consumed.findValue("TravelerInformation"))); + String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, "TravelerInformation"); + TravelerInformation timObject = (TravelerInformation)XmlUtils.fromXmlS(travelerInformationXml, TravelerInformation.class); + OdeTimPayload payload = new OdeTimPayload(timObject); return new OdeTimData(metadata, payload); } public static OdeTimData createOdeTimDataFromCreator(String consumedData, OdeMsgMetadata metadata) throws XmlUtilsException { - ObjectNode consumed = XmlUtils.toObjectNode(consumedData); - OdeTimPayload payload = new OdeTimPayload(TIMBuilder.genericTim(consumed.findValue("TravelerInformation"))); + String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, "TravelerInformation"); + TravelerInformation timObject = (TravelerInformation)XmlUtils.fromXmlS(travelerInformationXml, TravelerInformation.class); + OdeTimPayload payload = new OdeTimPayload(timObject); return new OdeTimData(metadata, payload); } } From d01ae2ac3ce120fadd962bb10fe5b9fa46cd13f9 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Tue, 3 Dec 2024 08:42:11 -0700 Subject: [PATCH 109/264] Formatted modified java files --- .../its/jpo/ode/inet/InetPacketSender.java | 300 +-- .../jpo/ode/model/OdeTravelerInputData.java | 7 +- .../dot/its/jpo/ode/model/OdeTimDataTest.java | 41 +- .../ode/model/OdeTravelerInputDataTest.java | 385 +-- .../j2735/OdeTravelerInformationMessage.java | 1685 +++++++------ ...ravelerMessageFromHumanToAsnConverter.java | 2098 +++++++++-------- .../ode/plugin/j2735/timstorage/Anchor.java | 71 +- .../jpo/ode/plugin/j2735/timstorage/Area.java | 9 +- .../ode/plugin/j2735/timstorage/Circle.java | 59 +- .../plugin/j2735/timstorage/ComputedLane.java | 18 +- .../ode/plugin/j2735/timstorage/Content.java | 30 +- .../plugin/j2735/timstorage/Description.java | 41 +- .../j2735/timstorage/DirectionOfUse.java | 18 +- .../j2735/timstorage/DistanceUnits.java | 23 +- .../ode/plugin/j2735/timstorage/Extent.java | 33 +- .../plugin/j2735/timstorage/FrameType.java | 77 +- .../j2735/timstorage/GeographicalPath.java | 128 +- .../j2735/timstorage/GeometricProjection.java | 75 +- .../jpo/ode/plugin/j2735/timstorage/Id.java | 37 +- .../j2735/timstorage/LaneDataAttribute.java | 2 +- .../timstorage/LaneDataAttributeList.java | 6 +- .../ode/plugin/j2735/timstorage/MsgId.java | 37 +- .../j2735/timstorage/NodeAttributeSetXY.java | 8 +- .../ode/plugin/j2735/timstorage/NodeLL.java | 28 +- .../plugin/j2735/timstorage/NodeListLL.java | 28 +- .../plugin/j2735/timstorage/NodeListXY.java | 9 +- .../j2735/timstorage/NodeOffsetPointXY.java | 237 +- .../plugin/j2735/timstorage/NodeSetXY.java | 6 +- .../ode/plugin/j2735/timstorage/NodeXY.java | 7 +- .../ode/plugin/j2735/timstorage/Node_XY.java | 37 +- .../ode/plugin/j2735/timstorage/Nodes.java | 45 +- .../ode/plugin/j2735/timstorage/Offset.java | 7 +- .../plugin/j2735/timstorage/OffsetAxis.java | 39 +- .../plugin/j2735/timstorage/OffsetSystem.java | 37 +- .../ode/plugin/j2735/timstorage/Position.java | 73 +- .../plugin/j2735/timstorage/RegionList.java | 6 +- .../j2735/timstorage/RegionOffsets.java | 12 +- .../j2735/timstorage/RegionPointSet.java | 11 +- .../ode/plugin/j2735/timstorage/Regions.java | 7 +- .../timstorage/RegulatorySpeedLimit.java | 9 +- .../j2735/timstorage/ShapePointSet.java | 11 +- .../j2735/timstorage/SpeedLimitList.java | 4 +- .../j2735/timstorage/SpeedLimitType.java | 35 +- .../j2735/timstorage/TravelerDataFrame.java | 274 +-- .../plugin/j2735/timstorage/ValidRegion.java | 7 +- .../timstorage/TravelerDataFrameTest.java | 9 +- .../traveler/TimDepositControllerTest.java | 345 +-- .../ode/traveler/TimTransmogrifierTest.java | 654 ++--- 48 files changed, 3695 insertions(+), 3430 deletions(-) diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java index 49cabf798..333d30ee2 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.inet; import java.io.IOException; @@ -21,7 +22,6 @@ import java.net.SocketException; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.eventlog.EventLogger; /** * Sender/Forwarder helper class for use by Forwarder, Transport, and Data Sink @@ -30,147 +30,155 @@ @Slf4j public class InetPacketSender { - private static final String INVALID_PARAMETERS_MSG = "Invalid Parameters. Parameters destination point and payload can not be null"; - - /** - * Inet address and port to forward packets to - */ - private InetPoint frwdPoint; - - /** - * Specifies whether outbound IPv4 messages should be send directly or - * forwarded. Default is send directly. - * To force forwarding IPv4 messages, set this variable to true. - */ - private boolean forwardAll; - - public InetPacketSender() { - } - - /** - * Creates an instance of the forwarder/sender helper class. - * - * @param frwdPoint is the destination to use for forwarding - */ - public InetPacketSender(InetPoint frwdPoint) { - this.frwdPoint = frwdPoint; - } - - /** - * Forward packet. Intended client is the forwarder that received a packet - * - * @param packet UDP packet - * @throws InetPacketException - */ - public void forward(DatagramPacket packet) throws InetPacketException { - if (packet == null) { - log.warn("Ignoring forward request for null packet"); - return; - } - if (frwdPoint == null) - throw new InetPacketException("Couldn't forward packet. Reason: Forwarding destination is not defined."); - send(frwdPoint, new InetPacket(packet).getBundle()); - } - - /** - * Send packet. Intended client is the forwarder that sends outbound packet - * - * @param packet outbound packet that contains destination+payload bundle - * @throws InetPacketException - */ - public void send(DatagramPacket packet) throws InetPacketException { - if (packet == null) { - log.warn("Ignoring send request for null packet"); - return; - } - InetPacket p = new InetPacket(packet); - InetPoint point = p.getPoint(); - if (point == null) - throw new InetPacketException( - "Couldn't send packet. Reason: Destination is not defined in the packet (not a bundle?)"); - send(point, p.getPayload()); - } - - /** - * Forward payload to be sent to dstPoint. Intended clients are Transport or - * Data Sink sending via forwarder - * - * @param dstPoint destination address and port for forwarder to forward to - * @param payload data to forward - * @throws InetPacketException - */ - public void forward(InetPoint dstPoint, byte[] payload) throws InetPacketException { - if (dstPoint == null || payload == null) - throw new InetPacketException(INVALID_PARAMETERS_MSG); - if (frwdPoint == null) - log.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); - if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll())) { - send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); - } else { - log.debug("Using direct send instead of forwarding"); - send(dstPoint, payload); - } - } - - /** - * Forward payload to be sent to dstPoint. Intended clients are Transport or - * Data Sink sending via forwarder or direct - * - * @param dstPoint destination address and port of the final destination - * @param payload data to forward or send - * @param fromForwarder whether the original request came through a forwarder - * @throws InetPacketException - */ - public void forward(InetPoint dstPoint, byte[] payload, boolean fromForwarder) throws InetPacketException { - if (dstPoint == null || payload == null) - throw new InetPacketException(INVALID_PARAMETERS_MSG); - if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll() || fromForwarder)) { - send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); - } else { - log.debug("Using direct send instead of forwarding"); - send(dstPoint, payload); - } - } - - /** - * Send payload to the destination specified. Intended clients are Transport or - * Data Sink sending directly to the client - * - * @param dstPoint destination address and port to send to - * @param payload data to send - * @throws InetPacketException - */ - public void send(InetPoint dstPoint, byte[] payload) throws InetPacketException { - if (dstPoint == null || payload == null) - throw new InetPacketException(INVALID_PARAMETERS_MSG); - try (DatagramSocket sock = new DatagramSocket()) { - DatagramPacket packet = new DatagramPacket(payload, payload.length, dstPoint.getInetAddress(), - dstPoint.port); - sock.send(packet); - } catch (SocketException ex) { - throw new InetPacketException("Couldn't send packet because socket closed.", ex); - } catch (IOException ex) { - throw new InetPacketException("Couldn't send packet due to IO exception.", ex); - } - } - - /** - * Reports whether outbound IPv4 messages should be send directly or forwarded. - * - * @return true if IPv4 packets are forwarded in addition to IPv6 packets - */ - public boolean isForwardAll() { - return forwardAll; - } - - /** - * - * @param forwardAll Directs how to handle IPv4 messages. - * Specify true to force forwarding IPv4 messages, and false - * to always send them directly. - */ - public void setForwardAll(boolean forwardAll) { - this.forwardAll = forwardAll; - } + private static final String INVALID_PARAMETERS_MSG = + "Invalid Parameters. Parameters destination point and payload can not be null"; + + /** + * Inet address and port to forward packets to + */ + private InetPoint frwdPoint; + + /** + * Specifies whether outbound IPv4 messages should be send directly or + * forwarded. Default is send directly. + * To force forwarding IPv4 messages, set this variable to true. + */ + private boolean forwardAll; + + public InetPacketSender() { + } + + /** + * Creates an instance of the forwarder/sender helper class. + * + * @param frwdPoint is the destination to use for forwarding + */ + public InetPacketSender(InetPoint frwdPoint) { + this.frwdPoint = frwdPoint; + } + + /** + * Forward packet. Intended client is the forwarder that received a packet + * + * @param packet UDP packet + * @throws InetPacketException + */ + public void forward(DatagramPacket packet) throws InetPacketException { + if (packet == null) { + log.warn("Ignoring forward request for null packet"); + return; + } + if (frwdPoint == null) { + throw new InetPacketException( + "Couldn't forward packet. Reason: Forwarding destination is not defined."); + } + send(frwdPoint, new InetPacket(packet).getBundle()); + } + + /** + * Send packet. Intended client is the forwarder that sends outbound packet + * + * @param packet outbound packet that contains destination+payload bundle + * @throws InetPacketException + */ + public void send(DatagramPacket packet) throws InetPacketException { + if (packet == null) { + log.warn("Ignoring send request for null packet"); + return; + } + InetPacket p = new InetPacket(packet); + InetPoint point = p.getPoint(); + if (point == null) { + throw new InetPacketException( + "Couldn't send packet. Reason: Destination is not defined in the packet (not a bundle?)"); + } + send(point, p.getPayload()); + } + + /** + * Forward payload to be sent to dstPoint. Intended clients are Transport or + * Data Sink sending via forwarder + * + * @param dstPoint destination address and port for forwarder to forward to + * @param payload data to forward + * @throws InetPacketException + */ + public void forward(InetPoint dstPoint, byte[] payload) throws InetPacketException { + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } + if (frwdPoint == null) { + log.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); + } + if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll())) { + send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); + } else { + log.debug("Using direct send instead of forwarding"); + send(dstPoint, payload); + } + } + + /** + * Forward payload to be sent to dstPoint. Intended clients are Transport or + * Data Sink sending via forwarder or direct + * + * @param dstPoint destination address and port of the final destination + * @param payload data to forward or send + * @param fromForwarder whether the original request came through a forwarder + * @throws InetPacketException + */ + public void forward(InetPoint dstPoint, byte[] payload, boolean fromForwarder) + throws InetPacketException { + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } + if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll() || fromForwarder)) { + send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); + } else { + log.debug("Using direct send instead of forwarding"); + send(dstPoint, payload); + } + } + + /** + * Send payload to the destination specified. Intended clients are Transport or + * Data Sink sending directly to the client + * + * @param dstPoint destination address and port to send to + * @param payload data to send + * @throws InetPacketException + */ + public void send(InetPoint dstPoint, byte[] payload) throws InetPacketException { + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } + try (DatagramSocket sock = new DatagramSocket()) { + DatagramPacket packet = new DatagramPacket(payload, payload.length, dstPoint.getInetAddress(), + dstPoint.port); + sock.send(packet); + } catch (SocketException ex) { + throw new InetPacketException("Couldn't send packet because socket closed.", ex); + } catch (IOException ex) { + throw new InetPacketException("Couldn't send packet due to IO exception.", ex); + } + } + + /** + * Reports whether outbound IPv4 messages should be send directly or forwarded. + * + * @return true if IPv4 packets are forwarded in addition to IPv6 packets + */ + public boolean isForwardAll() { + return forwardAll; + } + + /** + * @param forwardAll Directs how to handle IPv4 messages. + * Specify true to force forwarding IPv4 messages, and false + * to always send them directly. + */ + public void setForwardAll(boolean forwardAll) { + this.forwardAll = forwardAll; + } } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java index 9505168a4..4462dd0f9 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTravelerInputData.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.model; import lombok.Data; diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java index 8422b3f69..feb7e3016 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java @@ -15,22 +15,27 @@ import static org.junit.Assert.*; public class OdeTimDataTest { - private static final String SCHEMA_VERSION = "7"; - private static final String ASN1_STRING = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e"; - - private static final String json = String.format("{\"metadata\":{\"securityResultCode\":\"\",\"recordGeneratedBy\":\"RSU\",\"schemaVersion\":\"%s\",\"odePacketID\":\"\",\"sanitized\":\"false\",\"asn1\":\"%s\",\"recordType\":\"timMsg\",\"recordGeneratedAt\":\"\",\"maxDurationTime\":\"0\",\"odeTimStartDateTime\":\"\",\"receivedMessageDetails\":\"\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"recordId\":\"0\",\"serialNumber\":\"0\",\"streamId\":\"11ad5323-ec81-4694-8cd0-eb88ca08728e\",\"bundleSize\":\"1\",\"bundleId\":\"0\"},\"logFileName\":\"\",\"odeReceivedAt\":\"2022-12-24T02:24:38.248417Z\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"data\":{\"MessageFrame\":{\"messageId\":\"31\",\"value\":{\"TravelerInformation\":{\"timeStamp\":\"449089\",\"packetID\":\"0000000000000BBC2B\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":{\"regions\":{\"GeographicalPath\":{\"closedPath\":{\"false\":\"\"},\"anchor\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"},\"name\":\"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456\",\"laneWidth\":\"32700\",\"directionality\":{\"both\":\"\"},\"description\":{\"path\":{\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047287423\",\"lat\":\"411264686\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047305390\",\"lat\":\"411260104\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047323629\",\"lat\":\"411256185\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047342080\",\"lat\":\"411252886\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047360706\",\"lat\":\"411250207\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047379480\",\"lat\":\"411248201\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047398354\",\"lat\":\"411246839\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047417290\",\"lat\":\"411246133\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047436246\",\"lat\":\"411245796\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047455202\",\"lat\":\"411245470\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047474159\",\"lat\":\"411245173\"}}}]}}},\"scale\":\"0\"}},\"id\":{\"id\":\"0\",\"region\":\"0\"},\"direction\":\"0000000000010000\"}},\"durationTime\":\"1440\",\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":\"2018\",\"msgId\":{\"roadSignID\":{\"viewAngle\":\"1111111111111111\",\"mutcdCode\":{\"warning\":\"\"},\"position\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"}}},\"priority\":\"5\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"777\"}},{\"item\":{\"itis\":\"13579\"}}]}},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"frameType\":{\"advisory\":\"\"},\"startTime\":\"448260\"}},\"msgCnt\":\"1\"}}}},\"dataType\":\"TravelerInformation\"}}", SCHEMA_VERSION, ASN1_STRING); - - // - // Note that OdeTimData does not have annotations to support deserialization, so serialization/deserialization is not tested here. - // - - @Test - public void shouldValidateJson() throws Exception { - // Load json schema from resource - JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); - final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-tim.json").toURI()); - final JsonNode node = (JsonNode)JsonUtils.fromJson(json, JsonNode.class); - Set validationMessages = schema.validate(node); - assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); - } + private static final String SCHEMA_VERSION = "7"; + private static final String ASN1_STRING = + "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e"; + + private static final String json = String.format( + "{\"metadata\":{\"securityResultCode\":\"\",\"recordGeneratedBy\":\"RSU\",\"schemaVersion\":\"%s\",\"odePacketID\":\"\",\"sanitized\":\"false\",\"asn1\":\"%s\",\"recordType\":\"timMsg\",\"recordGeneratedAt\":\"\",\"maxDurationTime\":\"0\",\"odeTimStartDateTime\":\"\",\"receivedMessageDetails\":\"\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"recordId\":\"0\",\"serialNumber\":\"0\",\"streamId\":\"11ad5323-ec81-4694-8cd0-eb88ca08728e\",\"bundleSize\":\"1\",\"bundleId\":\"0\"},\"logFileName\":\"\",\"odeReceivedAt\":\"2022-12-24T02:24:38.248417Z\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"data\":{\"MessageFrame\":{\"messageId\":\"31\",\"value\":{\"TravelerInformation\":{\"timeStamp\":\"449089\",\"packetID\":\"0000000000000BBC2B\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":{\"regions\":{\"GeographicalPath\":{\"closedPath\":{\"false\":\"\"},\"anchor\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"},\"name\":\"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456\",\"laneWidth\":\"32700\",\"directionality\":{\"both\":\"\"},\"description\":{\"path\":{\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047287423\",\"lat\":\"411264686\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047305390\",\"lat\":\"411260104\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047323629\",\"lat\":\"411256185\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047342080\",\"lat\":\"411252886\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047360706\",\"lat\":\"411250207\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047379480\",\"lat\":\"411248201\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047398354\",\"lat\":\"411246839\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047417290\",\"lat\":\"411246133\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047436246\",\"lat\":\"411245796\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047455202\",\"lat\":\"411245470\"}}},{\"delta\":{\"node-LatLon\":{\"lon\":\"-1047474159\",\"lat\":\"411245173\"}}}]}}},\"scale\":\"0\"}},\"id\":{\"id\":\"0\",\"region\":\"0\"},\"direction\":\"0000000000010000\"}},\"durationTime\":\"1440\",\"doNotUse3\":0,\"doNotUse4\":0,\"startYear\":\"2018\",\"msgId\":{\"roadSignID\":{\"viewAngle\":\"1111111111111111\",\"mutcdCode\":{\"warning\":\"\"},\"position\":{\"lat\":\"411269876\",\"long\":\"-1047269563\"}}},\"priority\":\"5\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"777\"}},{\"item\":{\"itis\":\"13579\"}}]}},\"url\":\"null\",\"doNotUse1\":0,\"doNotUse2\":0,\"frameType\":{\"advisory\":\"\"},\"startTime\":\"448260\"}},\"msgCnt\":\"1\"}}}},\"dataType\":\"TravelerInformation\"}}", + SCHEMA_VERSION, ASN1_STRING); + + // + // Note that OdeTimData does not have annotations to support deserialization, so serialization/deserialization is not tested here. + // + + @Test + public void shouldValidateJson() throws Exception { + // Load json schema from resource + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); + final JsonSchema schema = factory.getSchema( + getClass().getClassLoader().getResource("schemas/schema-tim.json").toURI()); + final JsonNode node = (JsonNode) JsonUtils.fromJson(json, 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/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java index a8df913d3..d386cd004 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTravelerInputDataTest.java @@ -20,205 +20,208 @@ class OdeTravelerInputDataTest { - /** - * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 - * Prior to J2735 2016, the following fields had different names: - * - 'doNotUse1' was 'sspTimRights' - * - 'doNotUse2' was 'sspLocationRights' - * - 'doNotUse3' was 'sspMsgContent' - * - 'doNotUse4' was 'sspMsgTypes' - * - 'durationTime' was 'duratonTime' - */ - @Test - void testConvertPreJ2735_2016ToJ2735_2024() throws IOException { - // prepare - String timRequestPreJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); - ObjectMapper mapper = new ObjectMapper(); - OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + /** + * Test method for converting pre-J2735-2016 ASN.1 to J2735-2024 ASN.1 + * Prior to J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgContent' + * - 'doNotUse4' was 'sspMsgTypes' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertPreJ2735_2016ToJ2735_2024() throws IOException { + // prepare + String timRequestPreJ2735_2016 = new String(Files.readAllBytes( + Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_pre-J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); - // execute - val deserializedTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); + // execute + val deserializedTID = mapper.readValue(timRequestPreJ2735_2016, OdeTravelerInputData.class); - // verify (compare inputTID to an expected OdeTravelerInputData object) - Assertions.assertEquals(expectedTID, deserializedTID); - } + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } - /** - * Test method for converting J2735-2016 ASN.1 to J2735-2024 ASN.1 - * In J2735 2016, the following fields had different names: - * - 'doNotUse1' was 'sspTimRights' - * - 'doNotUse2' was 'sspLocationRights' - * - 'doNotUse3' was 'sspMsgRights1' - * - 'doNotUse4' was 'sspMsgRights2' - * - 'durationTime' was 'duratonTime' - */ - @Test - void testConvertJ2735_2016ToJ2735_2024() throws IOException { - // prepare - String timRequestJ2735_2016 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2016.json"))); - ObjectMapper mapper = new ObjectMapper(); - OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + /** + * Test method for converting J2735-2016 ASN.1 to J2735-2024 ASN.1 + * In J2735 2016, the following fields had different names: + * - 'doNotUse1' was 'sspTimRights' + * - 'doNotUse2' was 'sspLocationRights' + * - 'doNotUse3' was 'sspMsgRights1' + * - 'doNotUse4' was 'sspMsgRights2' + * - 'durationTime' was 'duratonTime' + */ + @Test + void testConvertJ2735_2016ToJ2735_2024() throws IOException { + // prepare + String timRequestJ2735_2016 = new String(Files.readAllBytes( + Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2016.json"))); + ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); - // execute - val deserializedTID = mapper.readValue(timRequestJ2735_2016, OdeTravelerInputData.class); + // execute + val deserializedTID = mapper.readValue(timRequestJ2735_2016, OdeTravelerInputData.class); - // verify (compare inputTID to an expected OdeTravelerInputData object) - Assertions.assertEquals(expectedTID, deserializedTID); - } + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } - /** - * Test method for converting J2735-2020 ASN.1 to J2735-2024 ASN.1 - * In J2735 2020, the following fields had different names: - * - 'doNotUse1' was 'notUsed' - * - 'doNotUse2' was 'notUsed1' - * - 'doNotUse3' was 'notUsed2' - * - 'doNotUse4' was 'notUsed3' - */ - @Test - void testConvertJ2735_2020ToJ2735_2024() throws IOException { - // prepare - String timRequestJ2735_2020 = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2020.json"))); - ObjectMapper mapper = new ObjectMapper(); - OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); + /** + * Test method for converting J2735-2020 ASN.1 to J2735-2024 ASN.1 + * In J2735 2020, the following fields had different names: + * - 'doNotUse1' was 'notUsed' + * - 'doNotUse2' was 'notUsed1' + * - 'doNotUse3' was 'notUsed2' + * - 'doNotUse4' was 'notUsed3' + */ + @Test + void testConvertJ2735_2020ToJ2735_2024() throws IOException { + // prepare + String timRequestJ2735_2020 = new String(Files.readAllBytes( + Paths.get("src/test/resources/us/dot/its/jpo/ode/model/timRequest_J2735-2020.json"))); + ObjectMapper mapper = new ObjectMapper(); + OdeTravelerInputData expectedTID = getExpectedDeserializedObject(); - // execute - val deserializedTID = mapper.readValue(timRequestJ2735_2020, OdeTravelerInputData.class); + // execute + val deserializedTID = mapper.readValue(timRequestJ2735_2020, OdeTravelerInputData.class); - // verify (compare inputTID to an expected OdeTravelerInputData object) - Assertions.assertEquals(expectedTID, deserializedTID); - } + // verify (compare inputTID to an expected OdeTravelerInputData object) + Assertions.assertEquals(expectedTID, deserializedTID); + } - private static OdeTravelerInputData getExpectedDeserializedObject() { - OdeTravelerInputData expected = new OdeTravelerInputData(); - var req = new ServiceRequest(); - var rsu = new RoadSideUnit.RSU(); - rsu.setRsuTarget("127.0.0.2"); - rsu.setRsuUsername("v3user"); - rsu.setRsuPassword("password"); - rsu.setRsuRetries(1); - rsu.setRsuTimeout(1000); - rsu.setRsuIndex(10); - rsu.setSnmpProtocol(SnmpProtocol.valueOf("NTCIP1218")); - req.setRsus(new RoadSideUnit.RSU[]{rsu}); - var snmp = new SNMP(); - snmp.setRsuid("00000083"); - snmp.setMsgid(31); - snmp.setMode(1); - snmp.setChannel(178); - snmp.setInterval(2); - snmp.setDeliverystart("2017-06-01T17:47:11-05:00"); - snmp.setDeliverystop("2018-01-01T17:47:11-05:15"); - snmp.setEnable(1); - snmp.setStatus(4); - req.setSnmp(snmp); - expected.setRequest(req); - var tim = new OdeTravelerInformationMessage(); - tim.setMsgCnt(1); - tim.setTimeStamp("2017-08-03T22:25:36.297Z"); - tim.setPacketID("EC9C236B0000000000"); - tim.setUrlB("null"); - var dataframes = new OdeTravelerInformationMessage.DataFrame[1]; - var df = new OdeTravelerInformationMessage.DataFrame(); - df.setDoNotUse1((short)0); - df.setFrameType(FrameType.TravelerInfoType.valueOf("advisory")); - var msgId = new OdeTravelerInformationMessage.DataFrame.MsgId(); - var roadSignID = new OdeTravelerInformationMessage.DataFrame.RoadSignID(); - var position = new OdePosition3D(); - position.setLatitude(new BigDecimal("41.678473")); - position.setLongitude(new BigDecimal("-108.782775")); - position.setElevation(new BigDecimal("917.1432")); - roadSignID.setPosition(position); - roadSignID.setViewAngle("1010101010101010"); - roadSignID.setMutcdCode(MutcdCode.MutcdCodeEnum.valueOf("warning")); - roadSignID.setCrc("0000"); - msgId.setRoadSignID(roadSignID); - df.setMsgId(msgId); - df.setStartDateTime("2017-08-02T22:25:00.000Z"); - df.setDurationTime(1); - df.setPriority(0); - df.setDoNotUse2((short)0); - var region = new OdeTravelerInformationMessage.DataFrame.Region(); - region.setName("Testing TIM"); - region.setRegulatorID(0); - region.setSegmentID(33); - var anchorPosition = new OdePosition3D(); - anchorPosition.setLatitude(new BigDecimal("41.2500807")); - anchorPosition.setLongitude(new BigDecimal("-111.0093847")); - anchorPosition.setElevation(new BigDecimal("2020.6969900289998")); - region.setAnchorPosition(anchorPosition); - region.setLaneWidth(BigDecimal.valueOf(7)); - region.setDirectionality("3"); - region.setClosedPath(false); - region.setDirection("0000000000001010"); - region.setDescription("path"); - var path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); - path.setScale(0); - path.setType("ll"); - var nodes = new OdeTravelerInformationMessage.NodeXY[13]; - nodes[0] = new OdeTravelerInformationMessage.NodeXY(); - nodes[0].setDelta("node-LL"); - nodes[0].setNodeLat(BigDecimal.valueOf(-0.0002048)); - nodes[0].setNodeLong(BigDecimal.valueOf(0.0002047)); - nodes[1] = new OdeTravelerInformationMessage.NodeXY(); - nodes[1].setDelta("node-LL"); - nodes[1].setNodeLat(BigDecimal.valueOf(-0.0008192)); - nodes[1].setNodeLong(BigDecimal.valueOf(0.0008191)); - nodes[2] = new OdeTravelerInformationMessage.NodeXY(); - nodes[2].setDelta("node-LL"); - nodes[2].setNodeLat(BigDecimal.valueOf(-0.0032768)); - nodes[2].setNodeLong(BigDecimal.valueOf(0.0032767)); - nodes[3] = new OdeTravelerInformationMessage.NodeXY(); - nodes[3].setDelta("node-LL"); - nodes[3].setNodeLat(BigDecimal.valueOf(-0.0131072)); - nodes[3].setNodeLong(BigDecimal.valueOf(0.0131071)); - nodes[4] = new OdeTravelerInformationMessage.NodeXY(); - nodes[4].setDelta("node-LL"); - nodes[4].setNodeLat(BigDecimal.valueOf(-0.2097152)); - nodes[4].setNodeLong(BigDecimal.valueOf(0.2097151)); - nodes[5] = new OdeTravelerInformationMessage.NodeXY(); - nodes[5].setDelta("node-LL"); - nodes[5].setNodeLat(BigDecimal.valueOf(-0.8388608)); - nodes[5].setNodeLong(BigDecimal.valueOf(0.8388607)); - nodes[6] = new OdeTravelerInformationMessage.NodeXY(); - nodes[6].setDelta("node-LL1"); - nodes[6].setNodeLat(BigDecimal.valueOf(-0.0002048)); - nodes[6].setNodeLong(BigDecimal.valueOf(0.0002047)); - nodes[7] = new OdeTravelerInformationMessage.NodeXY(); - nodes[7].setDelta("node-LL2"); - nodes[7].setNodeLat(BigDecimal.valueOf(-0.0008192)); - nodes[7].setNodeLong(BigDecimal.valueOf(0.0008191)); - nodes[8] = new OdeTravelerInformationMessage.NodeXY(); - nodes[8].setDelta("node-LL3"); - nodes[8].setNodeLat(BigDecimal.valueOf(-0.0032768)); - nodes[8].setNodeLong(BigDecimal.valueOf(0.0032767)); - nodes[9] = new OdeTravelerInformationMessage.NodeXY(); - nodes[9].setDelta("node-LL4"); - nodes[9].setNodeLat(BigDecimal.valueOf(-0.0131072)); - nodes[9].setNodeLong(BigDecimal.valueOf(0.0131071)); - nodes[10] = new OdeTravelerInformationMessage.NodeXY(); - nodes[10].setDelta("node-LL5"); - nodes[10].setNodeLat(BigDecimal.valueOf(-0.2097152)); - nodes[10].setNodeLong(BigDecimal.valueOf(0.2097151)); - nodes[11] = new OdeTravelerInformationMessage.NodeXY(); - nodes[11].setDelta("node-LL6"); - nodes[11].setNodeLat(BigDecimal.valueOf(-0.8388608)); - nodes[11].setNodeLong(BigDecimal.valueOf(0.8388607)); - nodes[12] = new OdeTravelerInformationMessage.NodeXY(); - nodes[12].setDelta("node-LatLon"); - nodes[12].setNodeLat(BigDecimal.valueOf(41.2500807)); - nodes[12].setNodeLong(BigDecimal.valueOf(-111.0093847)); - path.setNodes(nodes); - region.setPath(path); - df.setRegions(new OdeTravelerInformationMessage.DataFrame.Region[]{region}); - df.setDoNotUse3((short)3); - df.setDoNotUse4((short)2); - df.setContent("Advisory"); - df.setItems(new String[]{"125", "some text", "250", "'98765"}); - df.setUrl("null"); - dataframes[0] = df; - tim.setDataframes(dataframes); - expected.setTim(tim); - return expected; - } + private static OdeTravelerInputData getExpectedDeserializedObject() { + OdeTravelerInputData expected = new OdeTravelerInputData(); + var req = new ServiceRequest(); + var rsu = new RoadSideUnit.RSU(); + rsu.setRsuTarget("127.0.0.2"); + rsu.setRsuUsername("v3user"); + rsu.setRsuPassword("password"); + rsu.setRsuRetries(1); + rsu.setRsuTimeout(1000); + rsu.setRsuIndex(10); + rsu.setSnmpProtocol(SnmpProtocol.valueOf("NTCIP1218")); + req.setRsus(new RoadSideUnit.RSU[] {rsu}); + var snmp = new SNMP(); + snmp.setRsuid("00000083"); + snmp.setMsgid(31); + snmp.setMode(1); + snmp.setChannel(178); + snmp.setInterval(2); + snmp.setDeliverystart("2017-06-01T17:47:11-05:00"); + snmp.setDeliverystop("2018-01-01T17:47:11-05:15"); + snmp.setEnable(1); + snmp.setStatus(4); + req.setSnmp(snmp); + expected.setRequest(req); + var tim = new OdeTravelerInformationMessage(); + tim.setMsgCnt(1); + tim.setTimeStamp("2017-08-03T22:25:36.297Z"); + tim.setPacketID("EC9C236B0000000000"); + tim.setUrlB("null"); + var dataframes = new OdeTravelerInformationMessage.DataFrame[1]; + var df = new OdeTravelerInformationMessage.DataFrame(); + df.setDoNotUse1((short) 0); + df.setFrameType(FrameType.TravelerInfoType.valueOf("advisory")); + var msgId = new OdeTravelerInformationMessage.DataFrame.MsgId(); + var roadSignID = new OdeTravelerInformationMessage.DataFrame.RoadSignID(); + var position = new OdePosition3D(); + position.setLatitude(new BigDecimal("41.678473")); + position.setLongitude(new BigDecimal("-108.782775")); + position.setElevation(new BigDecimal("917.1432")); + roadSignID.setPosition(position); + roadSignID.setViewAngle("1010101010101010"); + roadSignID.setMutcdCode(MutcdCode.MutcdCodeEnum.valueOf("warning")); + roadSignID.setCrc("0000"); + msgId.setRoadSignID(roadSignID); + df.setMsgId(msgId); + df.setStartDateTime("2017-08-02T22:25:00.000Z"); + df.setDurationTime(1); + df.setPriority(0); + df.setDoNotUse2((short) 0); + var region = new OdeTravelerInformationMessage.DataFrame.Region(); + region.setName("Testing TIM"); + region.setRegulatorID(0); + region.setSegmentID(33); + var anchorPosition = new OdePosition3D(); + anchorPosition.setLatitude(new BigDecimal("41.2500807")); + anchorPosition.setLongitude(new BigDecimal("-111.0093847")); + anchorPosition.setElevation(new BigDecimal("2020.6969900289998")); + region.setAnchorPosition(anchorPosition); + region.setLaneWidth(BigDecimal.valueOf(7)); + region.setDirectionality("3"); + region.setClosedPath(false); + region.setDirection("0000000000001010"); + region.setDescription("path"); + var path = new OdeTravelerInformationMessage.DataFrame.Region.Path(); + path.setScale(0); + path.setType("ll"); + var nodes = new OdeTravelerInformationMessage.NodeXY[13]; + nodes[0] = new OdeTravelerInformationMessage.NodeXY(); + nodes[0].setDelta("node-LL"); + nodes[0].setNodeLat(BigDecimal.valueOf(-0.0002048)); + nodes[0].setNodeLong(BigDecimal.valueOf(0.0002047)); + nodes[1] = new OdeTravelerInformationMessage.NodeXY(); + nodes[1].setDelta("node-LL"); + nodes[1].setNodeLat(BigDecimal.valueOf(-0.0008192)); + nodes[1].setNodeLong(BigDecimal.valueOf(0.0008191)); + nodes[2] = new OdeTravelerInformationMessage.NodeXY(); + nodes[2].setDelta("node-LL"); + nodes[2].setNodeLat(BigDecimal.valueOf(-0.0032768)); + nodes[2].setNodeLong(BigDecimal.valueOf(0.0032767)); + nodes[3] = new OdeTravelerInformationMessage.NodeXY(); + nodes[3].setDelta("node-LL"); + nodes[3].setNodeLat(BigDecimal.valueOf(-0.0131072)); + nodes[3].setNodeLong(BigDecimal.valueOf(0.0131071)); + nodes[4] = new OdeTravelerInformationMessage.NodeXY(); + nodes[4].setDelta("node-LL"); + nodes[4].setNodeLat(BigDecimal.valueOf(-0.2097152)); + nodes[4].setNodeLong(BigDecimal.valueOf(0.2097151)); + nodes[5] = new OdeTravelerInformationMessage.NodeXY(); + nodes[5].setDelta("node-LL"); + nodes[5].setNodeLat(BigDecimal.valueOf(-0.8388608)); + nodes[5].setNodeLong(BigDecimal.valueOf(0.8388607)); + nodes[6] = new OdeTravelerInformationMessage.NodeXY(); + nodes[6].setDelta("node-LL1"); + nodes[6].setNodeLat(BigDecimal.valueOf(-0.0002048)); + nodes[6].setNodeLong(BigDecimal.valueOf(0.0002047)); + nodes[7] = new OdeTravelerInformationMessage.NodeXY(); + nodes[7].setDelta("node-LL2"); + nodes[7].setNodeLat(BigDecimal.valueOf(-0.0008192)); + nodes[7].setNodeLong(BigDecimal.valueOf(0.0008191)); + nodes[8] = new OdeTravelerInformationMessage.NodeXY(); + nodes[8].setDelta("node-LL3"); + nodes[8].setNodeLat(BigDecimal.valueOf(-0.0032768)); + nodes[8].setNodeLong(BigDecimal.valueOf(0.0032767)); + nodes[9] = new OdeTravelerInformationMessage.NodeXY(); + nodes[9].setDelta("node-LL4"); + nodes[9].setNodeLat(BigDecimal.valueOf(-0.0131072)); + nodes[9].setNodeLong(BigDecimal.valueOf(0.0131071)); + nodes[10] = new OdeTravelerInformationMessage.NodeXY(); + nodes[10].setDelta("node-LL5"); + nodes[10].setNodeLat(BigDecimal.valueOf(-0.2097152)); + nodes[10].setNodeLong(BigDecimal.valueOf(0.2097151)); + nodes[11] = new OdeTravelerInformationMessage.NodeXY(); + nodes[11].setDelta("node-LL6"); + nodes[11].setNodeLat(BigDecimal.valueOf(-0.8388608)); + nodes[11].setNodeLong(BigDecimal.valueOf(0.8388607)); + nodes[12] = new OdeTravelerInformationMessage.NodeXY(); + nodes[12].setDelta("node-LatLon"); + nodes[12].setNodeLat(BigDecimal.valueOf(41.2500807)); + nodes[12].setNodeLong(BigDecimal.valueOf(-111.0093847)); + path.setNodes(nodes); + region.setPath(path); + df.setRegions(new OdeTravelerInformationMessage.DataFrame.Region[] {region}); + df.setDoNotUse3((short) 3); + df.setDoNotUse4((short) 2); + df.setContent("Advisory"); + df.setItems(new String[] {"125", "some text", "250", "'98765"}); + df.setUrl("null"); + dataframes[0] = df; + tim.setDataframes(dataframes); + expected.setTim(tim); + return expected; + } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index e6386597f..98607ef71 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -1,25 +1,24 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.databind.JsonNode; import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Objects; import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.model.OdeObject; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @@ -35,1014 +34,1014 @@ @EqualsAndHashCode(callSuper = false) public class OdeTravelerInformationMessage extends OdeObject { - private static final long serialVersionUID = -200529140190872305L; + private static final long serialVersionUID = -200529140190872305L; - private int msgCnt; - private String timeStamp; - private String packetID; - private String urlB; - private DataFrame[] dataframes; - private transient JsonNode asnDataFrames; + private int msgCnt; + private String timeStamp; + private String packetID; + private String urlB; + private DataFrame[] dataframes; + private transient JsonNode asnDataFrames; - public int getMsgCnt() { - return msgCnt; - } + public int getMsgCnt() { + return msgCnt; + } - public void setMsgCnt(int msgCnt) { - this.msgCnt = msgCnt; - } + public void setMsgCnt(int msgCnt) { + this.msgCnt = msgCnt; + } - public String getTimeStamp() { - return timeStamp; - } + public String getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(String timeStamp) { + this.timeStamp = timeStamp; + } + + public String getPacketID() { + return packetID; + } + + public void setPacketID(String packetID) { + this.packetID = packetID; + } + + public DataFrame[] getDataframes() { + return dataframes; + } + + public void setDataframes(DataFrame[] dataframes) { + this.dataframes = dataframes; + } + + public String getUrlB() { + return urlB; + } + + public void setUrlB(String urlB) { + this.urlB = urlB; + } + + public JsonNode getAsnDataFrames() { + return asnDataFrames; + } + + public void setAsnDataFrames(JsonNode stringDataFrames) { + this.asnDataFrames = stringDataFrames; + } + + public static class NodeListXY extends OdeObject { + private static final long serialVersionUID = 1L; + private ComputedLane computedLane; + private NodeXY[] nodexy; + + public ComputedLane getComputedLane() { + return computedLane; + } + + public void setComputedLane(ComputedLane computedLane) { + this.computedLane = computedLane; + } + + public NodeXY[] getNodexy() { + return nodexy; + } + + public void setNodexy(NodeXY[] nodexy) { + this.nodexy = nodexy; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class Area extends OdeObject { + private static final long serialVersionUID = 1L; + + private ShapePointSet shapepoint; + private Circle circle; + private RegionPointSet regionPoint; + + public ShapePointSet getShapepoint() { + return shapepoint; + } + + public void setShapepoint(ShapePointSet shapepoint) { + this.shapepoint = shapepoint; + } + + public Circle getCircle() { + return circle; + } + + public void setCircle(Circle circle) { + this.circle = circle; + } + + public RegionPointSet getRegionPoint() { + return regionPoint; + } + + public void setRegionPoint(RegionPointSet regionPoint) { + this.regionPoint = regionPoint; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class ComputedLane extends OdeObject { + + private static final long serialVersionUID = 7337344402648755924L; + private int referenceLaneId; + private BigDecimal offsetXaxis; + private BigDecimal offsetYaxis; + private BigDecimal rotateXY; + private BigDecimal scaleXaxis; + private BigDecimal scaleYaxis; + + public int getReferenceLaneId() { + return referenceLaneId; + } + + public void setReferenceLaneId(int referenceLaneId) { + this.referenceLaneId = referenceLaneId; + } + + public BigDecimal getOffsetXaxis() { + return offsetXaxis; + } + + public void setOffsetXaxis(BigDecimal offsetXaxis) { + this.offsetXaxis = offsetXaxis; + } + + public BigDecimal getOffsetYaxis() { + return offsetYaxis; + } + + public void setOffsetYaxis(BigDecimal offsetYaxis) { + this.offsetYaxis = offsetYaxis; + } + + public BigDecimal getRotateXY() { + return rotateXY; + } + + public void setRotateXY(BigDecimal rotateXY) { + this.rotateXY = rotateXY; + } + + public BigDecimal getScaleXaxis() { + return scaleXaxis; + } + + public void setScaleXaxis(BigDecimal scaleXaxis) { + this.scaleXaxis = scaleXaxis; + } + + public BigDecimal getScaleYaxis() { + return scaleYaxis; + } + + public void setScaleYaxis(BigDecimal scaleYaxis) { + this.scaleYaxis = scaleYaxis; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class NodeXY extends OdeObject { + + private static final long serialVersionUID = -3250256624514759524L; + private String delta; + private BigDecimal nodeLat; + private BigDecimal nodeLong; + private BigDecimal x; + private BigDecimal y; + private Attributes attributes; + + public String getDelta() { + return delta; + } + + public void setDelta(String delta) { + this.delta = delta; + } + + public BigDecimal getNodeLat() { + return nodeLat; + } + + public void setNodeLat(BigDecimal nodeLat) { + this.nodeLat = nodeLat; + } + + public BigDecimal getNodeLong() { + return nodeLong; + } + + public void setNodeLong(BigDecimal nodeLong) { + this.nodeLong = nodeLong; + } + + public BigDecimal getX() { + return x; + } + + public void setX(BigDecimal x) { + this.x = x; + } + + public BigDecimal getY() { + return y; + } + + public void setY(BigDecimal y) { + this.y = y; + } + + public Attributes getAttributes() { + return attributes; + } + + public void setAttributes(Attributes attributes) { + this.attributes = attributes; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class LocalNode extends OdeObject { + + private static final long serialVersionUID = 3872400520330034244L; + private long type; + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class DisabledList extends OdeObject { + + private static final long serialVersionUID = 1009869811306803991L; + private long type; + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class EnabledList extends OdeObject { + + private static final long serialVersionUID = 5797889223766230223L; + private long type; + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class SpeedLimits extends OdeObject { + + private static final long serialVersionUID = -8729406522600137038L; + private long type; + private BigDecimal velocity; + + public long getType() { + return type; + } + + public void setType(long type) { + this.type = type; + } + + public BigDecimal getVelocity() { + return velocity; + } + + public void setVelocity(BigDecimal velocity) { + this.velocity = velocity; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class DataList extends OdeObject { + + private static final long serialVersionUID = -1391200532738540024L; + private int pathEndpointAngle; + private BigDecimal laneCrownCenter; + private BigDecimal laneCrownLeft; + private BigDecimal laneCrownRight; + private BigDecimal laneAngle; + private SpeedLimits[] speedLimits; + + public int getPathEndpointAngle() { + return pathEndpointAngle; + } + + public void setPathEndpointAngle(int pathEndpointAngle) { + this.pathEndpointAngle = pathEndpointAngle; + } + + public BigDecimal getLaneCrownCenter() { + return laneCrownCenter; + } + + public void setLaneCrownCenter(BigDecimal laneCrownCenter) { + this.laneCrownCenter = laneCrownCenter; + } + + public BigDecimal getLaneCrownLeft() { + return laneCrownLeft; + } + + public void setLaneCrownLeft(BigDecimal laneCrownLeft) { + this.laneCrownLeft = laneCrownLeft; + } + + public BigDecimal getLaneCrownRight() { + return laneCrownRight; + } + + public void setLaneCrownRight(BigDecimal laneCrownRight) { + this.laneCrownRight = laneCrownRight; + } + + public BigDecimal getLaneAngle() { + return laneAngle; + } + + public void setLaneAngle(BigDecimal laneAngle) { + this.laneAngle = laneAngle; + } + + public SpeedLimits[] getSpeedLimits() { + return speedLimits; + } + + public void setSpeedLimits(SpeedLimits[] speedLimits) { + this.speedLimits = speedLimits; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class Attributes extends OdeObject { + + private static final long serialVersionUID = -6476758554962944513L; + private LocalNode[] localNodes; + private DisabledList[] disabledLists; + private EnabledList[] enabledLists; + private DataList[] dataLists; + private BigDecimal dWidth; + private BigDecimal dElevation; + + public LocalNode[] getLocalNodes() { + return localNodes; + } + + public void setLocalNodes(LocalNode[] localNodes) { + this.localNodes = localNodes; + } + + public DisabledList[] getDisabledLists() { + return disabledLists; + } + + public void setDisabledLists(DisabledList[] disabledLists) { + this.disabledLists = disabledLists; + } + + public EnabledList[] getEnabledLists() { + return enabledLists; + } + + public void setEnabledLists(EnabledList[] enabledLists) { + this.enabledLists = enabledLists; + } + + public DataList[] getDataLists() { + return dataLists; + } + + public void setDataLists(DataList[] dataLists) { + this.dataLists = dataLists; + } + + public BigDecimal getdWidth() { + return dWidth; + } + + public void setdWidth(BigDecimal dWidth) { + this.dWidth = dWidth; + } + + public BigDecimal getdElevation() { + return dElevation; + } + + public void setdElevation(BigDecimal dElevation) { + this.dElevation = dElevation; + } + } + + @EqualsAndHashCode(callSuper = false) + public static class DataFrame extends OdeObject { + + private static final long serialVersionUID = 537503046055742396L; + @JsonAlias({"sspTimRights", "notUsed"}) + private short doNotUse1;// Start Header Information + private FrameType.TravelerInfoType frameType; + private MsgId msgId; + private String startDateTime; + @JsonAlias("duratonTime") + private int durationTime; + private int priority;// End header Information + @JsonAlias({"sspLocationRights", "notUsed1"}) + private short doNotUse2;// Start Region Information + private Region[] regions; + @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) + private short doNotUse3;// Start content Information + @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) + private short doNotUse4; + private String content; + private String[] items; + private String url;// End content Information + + @EqualsAndHashCode(callSuper = false) + public static class Region extends OdeObject { + + private static final long serialVersionUID = 8011973280114768008L; + private String name; + private int regulatorID; + private int segmentID; + private OdePosition3D anchorPosition; + private BigDecimal laneWidth; + private String directionality; + private boolean closedPath; + private String direction; + private String description; + private Path path; + private Geometry geometry; + private OldRegion oldRegion; - public void setTimeStamp(String timeStamp) { - this.timeStamp = timeStamp; - } + @EqualsAndHashCode(callSuper = false) + public static class OldRegion extends OdeObject { - public String getPacketID() { - return packetID; - } + private static final long serialVersionUID = 1L; + private String direction; + private String extent; + private Area area; - public void setPacketID(String packetID) { - this.packetID = packetID; - } + @EqualsAndHashCode(callSuper = false) + public static class ShapePointSet extends OdeObject { - public DataFrame[] getDataframes() { - return dataframes; - } + private static final long serialVersionUID = 1L; + private OdePosition3D anchor; + private BigDecimal laneWidth; + private int directionality; + private NodeListXY nodeList; - public void setDataframes(DataFrame[] dataframes) { - this.dataframes = dataframes; - } + public OdePosition3D getAnchor() { + return anchor; + } - public String getUrlB() { - return urlB; - } + public void setAnchor(OdePosition3D anchor) { + this.anchor = anchor; + } - public void setUrlB(String urlB) { - this.urlB = urlB; - } + public BigDecimal getLaneWidth() { + return laneWidth; + } - public JsonNode getAsnDataFrames() { - return asnDataFrames; - } + public void setLaneWidth(BigDecimal laneWidth) { + this.laneWidth = laneWidth; + } - public void setAsnDataFrames(JsonNode stringDataFrames) { - this.asnDataFrames = stringDataFrames; - } + public int getDirectionality() { + return directionality; + } - public static class NodeListXY extends OdeObject { - private static final long serialVersionUID = 1L; - private ComputedLane computedLane; - private NodeXY[] nodexy; + public void setDirectionality(int directionality) { + this.directionality = directionality; + } - public ComputedLane getComputedLane() { - return computedLane; - } + public void setDirectionalityEnum(DirectionOfUseEnum directionalityEnum) { + this.directionality = directionalityEnum.ordinal(); + } - public void setComputedLane(ComputedLane computedLane) { - this.computedLane = computedLane; - } + public NodeListXY getNodeList() { + return nodeList; + } - public NodeXY[] getNodexy() { - return nodexy; - } + public void setNodeList(NodeListXY nodeList) { + this.nodeList = nodeList; + } + } - public void setNodexy(NodeXY[] nodexy) { - this.nodexy = nodexy; - } - } + @EqualsAndHashCode(callSuper = false) + public static class RegionPointSet extends OdeObject { - @EqualsAndHashCode(callSuper = false) - public static class Area extends OdeObject { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; + private OdePosition3D position; + private int scale; + private RegionList[] regionList; - private ShapePointSet shapepoint; - private Circle circle; - private RegionPointSet regionPoint; + @EqualsAndHashCode(callSuper = false) + public static class RegionList extends OdeObject { - public ShapePointSet getShapepoint() { - return shapepoint; - } + private static final long serialVersionUID = -5307620155601900634L; + private BigDecimal xOffset; + private BigDecimal yOffset; + private BigDecimal zOffset; - public void setShapepoint(ShapePointSet shapepoint) { - this.shapepoint = shapepoint; - } + public BigDecimal getzOffset() { + return zOffset; + } - public Circle getCircle() { - return circle; - } + public void setzOffset(BigDecimal zOffset) { + this.zOffset = zOffset; + } - public void setCircle(Circle circle) { - this.circle = circle; - } + public BigDecimal getyOffset() { + return yOffset; + } - public RegionPointSet getRegionPoint() { - return regionPoint; - } + public void setyOffset(BigDecimal yOffset) { + this.yOffset = yOffset; + } - public void setRegionPoint(RegionPointSet regionPoint) { - this.regionPoint = regionPoint; - } - } + public BigDecimal getxOffset() { + return xOffset; + } - @EqualsAndHashCode(callSuper = false) - public static class ComputedLane extends OdeObject { + public void setxOffset(BigDecimal xOffset) { + this.xOffset = xOffset; + } + } - private static final long serialVersionUID = 7337344402648755924L; - private int referenceLaneId; - private BigDecimal offsetXaxis; - private BigDecimal offsetYaxis; - private BigDecimal rotateXY; - private BigDecimal scaleXaxis; - private BigDecimal scaleYaxis; + public RegionList[] getRegionList() { + return regionList; + } - public int getReferenceLaneId() { - return referenceLaneId; - } + public void setRegionList(RegionList[] regionList) { + this.regionList = regionList; + } - public void setReferenceLaneId(int referenceLaneId) { - this.referenceLaneId = referenceLaneId; - } + public int getScale() { + return scale; + } - public BigDecimal getOffsetXaxis() { - return offsetXaxis; - } + public void setScale(int scale) { + this.scale = scale; + } - public void setOffsetXaxis(BigDecimal offsetXaxis) { - this.offsetXaxis = offsetXaxis; - } + public OdePosition3D getPosition() { + return position; + } - public BigDecimal getOffsetYaxis() { - return offsetYaxis; - } + public void setPosition(OdePosition3D position) { + this.position = position; + } + } - public void setOffsetYaxis(BigDecimal offsetYaxis) { - this.offsetYaxis = offsetYaxis; - } + public Area getArea() { + return area; + } - public BigDecimal getRotateXY() { - return rotateXY; - } + public void setArea(Area area) { + this.area = area; + } - public void setRotateXY(BigDecimal rotateXY) { - this.rotateXY = rotateXY; - } + public String getExtent() { + return extent; + } - public BigDecimal getScaleXaxis() { - return scaleXaxis; - } + public void setExtent(String extent) { + this.extent = extent; + } - public void setScaleXaxis(BigDecimal scaleXaxis) { - this.scaleXaxis = scaleXaxis; - } + public void setExtent(ExtentEnum extent) { + this.extent = extent.name(); + } - public BigDecimal getScaleYaxis() { - return scaleYaxis; - } + public String getDirection() { + return direction; + } - public void setScaleYaxis(BigDecimal scaleYaxis) { - this.scaleYaxis = scaleYaxis; + public void setDirection(String direction) { + this.direction = direction; + } } - } - @EqualsAndHashCode(callSuper = false) - public static class NodeXY extends OdeObject { + public static class Geometry extends OdeObject { - private static final long serialVersionUID = -3250256624514759524L; - private String delta; - private BigDecimal nodeLat; - private BigDecimal nodeLong; - private BigDecimal x; - private BigDecimal y; - private Attributes attributes; + private static final long serialVersionUID = -7664796173893464468L; + private String direction; + private int extent; + private BigDecimal laneWidth; + private Circle circle; - public String getDelta() { - return delta; - } + public Circle getCircle() { + return circle; + } - public void setDelta(String delta) { - this.delta = delta; - } + public void setCircle(Circle circle) { + this.circle = circle; + } - public BigDecimal getNodeLat() { - return nodeLat; - } + public BigDecimal getLaneWidth() { + return laneWidth; + } - public void setNodeLat(BigDecimal nodeLat) { - this.nodeLat = nodeLat; - } + public void setLaneWidth(BigDecimal laneWidth) { + this.laneWidth = laneWidth; + } - public BigDecimal getNodeLong() { - return nodeLong; - } + public int getExtent() { + return extent; + } - public void setNodeLong(BigDecimal nodeLong) { - this.nodeLong = nodeLong; - } + public void setExtent(int extent) { + this.extent = extent; + } - public BigDecimal getX() { - return x; - } + public String getDirection() { + return direction; + } - public void setX(BigDecimal x) { - this.x = x; + public void setDirection(String direction) { + this.direction = direction; + } } - public BigDecimal getY() { - return y; - } + @EqualsAndHashCode(callSuper = false) + public static class Circle extends OdeObject { - public void setY(BigDecimal y) { - this.y = y; - } + private static final long serialVersionUID = -8156052898034497978L; + private OdePosition3D position; + private OdePosition3D center; + private int radius; + private String units; - public Attributes getAttributes() { - return attributes; - } + public String getUnits() { + return units; + } - public void setAttributes(Attributes attributes) { - this.attributes = attributes; - } - } + public void setUnits(String units) { + this.units = units; + } - @EqualsAndHashCode(callSuper = false) - public static class LocalNode extends OdeObject { + public void setUnits(DistanceUnitsEnum units) { + this.units = units.name(); + } - private static final long serialVersionUID = 3872400520330034244L; - private long type; + public int getRadius() { + return radius; + } - public long getType() { - return type; - } + public void setRadius(int radius) { + this.radius = radius; + } - public void setType(long type) { - this.type = type; - } - } + public OdePosition3D getPosition() { + return position; + } - @EqualsAndHashCode(callSuper = false) - public static class DisabledList extends OdeObject { + public void setPosition(OdePosition3D position) { + this.position = position; + } - private static final long serialVersionUID = 1009869811306803991L; - private long type; + public OdePosition3D getCenter() { + return center; + } - public long getType() { - return type; + public void setCenter(OdePosition3D center) { + this.center = center; + } } - public void setType(long type) { - this.type = type; - } - } + @EqualsAndHashCode(callSuper = false) + public static class Path extends OdeObject { - @EqualsAndHashCode(callSuper = false) - public static class EnabledList extends OdeObject { + private static final long serialVersionUID = 3293758823626661508L; + private int scale; + private String type; + private NodeXY[] nodes; + private ComputedLane computedLane; - private static final long serialVersionUID = 5797889223766230223L; - private long type; + public ComputedLane getComputedLane() { + return computedLane; + } - public long getType() { - return type; - } + public void setComputedLane(ComputedLane computedLane) { + this.computedLane = computedLane; + } - public void setType(long type) { - this.type = type; - } - } + public NodeXY[] getNodes() { + return nodes; + } - @EqualsAndHashCode(callSuper = false) - public static class SpeedLimits extends OdeObject { + public void setNodes(NodeXY[] nodes) { + this.nodes = nodes; + } - private static final long serialVersionUID = -8729406522600137038L; - private long type; - private BigDecimal velocity; + public String getType() { + return type; + } - public long getType() { - return type; - } + public void setType(String type) { + this.type = type; + } - public void setType(long type) { - this.type = type; - } + public int getScale() { + return scale; + } - public BigDecimal getVelocity() { - return velocity; + public void setScale(int scale) { + this.scale = scale; + } } - public void setVelocity(BigDecimal velocity) { - this.velocity = velocity; + public OldRegion getOldRegion() { + return oldRegion; } - } - - @EqualsAndHashCode(callSuper = false) - public static class DataList extends OdeObject { - private static final long serialVersionUID = -1391200532738540024L; - private int pathEndpointAngle; - private BigDecimal laneCrownCenter; - private BigDecimal laneCrownLeft; - private BigDecimal laneCrownRight; - private BigDecimal laneAngle; - private SpeedLimits[] speedLimits; - - public int getPathEndpointAngle() { - return pathEndpointAngle; + public void setOldRegion(OldRegion oldRegion) { + this.oldRegion = oldRegion; } - public void setPathEndpointAngle(int pathEndpointAngle) { - this.pathEndpointAngle = pathEndpointAngle; + public Geometry getGeometry() { + return geometry; } - public BigDecimal getLaneCrownCenter() { - return laneCrownCenter; + public void setGeometry(Geometry geometry) { + this.geometry = geometry; } - public void setLaneCrownCenter(BigDecimal laneCrownCenter) { - this.laneCrownCenter = laneCrownCenter; + public Path getPath() { + return path; } - public BigDecimal getLaneCrownLeft() { - return laneCrownLeft; + public void setPath(Path path) { + this.path = path; } - public void setLaneCrownLeft(BigDecimal laneCrownLeft) { - this.laneCrownLeft = laneCrownLeft; + public String getDescription() { + return description; } - public BigDecimal getLaneCrownRight() { - return laneCrownRight; + public void setDescription(String description) { + this.description = description; } - public void setLaneCrownRight(BigDecimal laneCrownRight) { - this.laneCrownRight = laneCrownRight; + public String getDirection() { + return direction; } - public BigDecimal getLaneAngle() { - return laneAngle; + public void setDirection(String direction) { + this.direction = direction; } - public void setLaneAngle(BigDecimal laneAngle) { - this.laneAngle = laneAngle; + public boolean isClosedPath() { + return closedPath; } - public SpeedLimits[] getSpeedLimits() { - return speedLimits; + public void setClosedPath(boolean closedPath) { + this.closedPath = closedPath; } - public void setSpeedLimits(SpeedLimits[] speedLimits) { - this.speedLimits = speedLimits; - } - } - - @EqualsAndHashCode(callSuper = false) - public static class Attributes extends OdeObject { - - private static final long serialVersionUID = -6476758554962944513L; - private LocalNode[] localNodes; - private DisabledList[] disabledLists; - private EnabledList[] enabledLists; - private DataList[] dataLists; - private BigDecimal dWidth; - private BigDecimal dElevation; - - public LocalNode[] getLocalNodes() { - return localNodes; + public String getDirectionality() { + return directionality; } - public void setLocalNodes(LocalNode[] localNodes) { - this.localNodes = localNodes; + public void setDirectionality(String directionality) { + this.directionality = directionality; } - public DisabledList[] getDisabledLists() { - return disabledLists; + public BigDecimal getLaneWidth() { + return laneWidth; } - public void setDisabledLists(DisabledList[] disabledLists) { - this.disabledLists = disabledLists; + public void setLaneWidth(BigDecimal laneWidth) { + this.laneWidth = laneWidth; } - public EnabledList[] getEnabledLists() { - return enabledLists; + public OdePosition3D getAnchorPosition() { + return anchorPosition; } - public void setEnabledLists(EnabledList[] enabledLists) { - this.enabledLists = enabledLists; + public void setAnchorPosition(OdePosition3D anchorPosition) { + this.anchorPosition = anchorPosition; } - public DataList[] getDataLists() { - return dataLists; + public int getSegmentID() { + return segmentID; } - public void setDataLists(DataList[] dataLists) { - this.dataLists = dataLists; + public void setSegmentID(int segmentID) { + this.segmentID = segmentID; } - public BigDecimal getdWidth() { - return dWidth; + public int getRegulatorID() { + return regulatorID; } - public void setdWidth(BigDecimal dWidth) { - this.dWidth = dWidth; + public void setRegulatorID(int regulatorID) { + this.regulatorID = regulatorID; } - public BigDecimal getdElevation() { - return dElevation; + public String getName() { + return name; } - public void setdElevation(BigDecimal dElevation) { - this.dElevation = dElevation; + public void setName(String name) { + this.name = name; } - } - - @EqualsAndHashCode(callSuper = false) - public static class DataFrame extends OdeObject { - - private static final long serialVersionUID = 537503046055742396L; - @JsonAlias({"sspTimRights", "notUsed"}) - private short doNotUse1;// Start Header Information - private FrameType.TravelerInfoType frameType; - private MsgId msgId; - private String startDateTime; - @JsonAlias("duratonTime") - private int durationTime; - private int priority;// End header Information - @JsonAlias({"sspLocationRights", "notUsed1"}) - private short doNotUse2;// Start Region Information - private Region[] regions; - @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) - private short doNotUse3;// Start content Information - @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) - private short doNotUse4; - private String content; - private String[] items; - private String url;// End content Information - - @EqualsAndHashCode(callSuper = false) - public static class Region extends OdeObject { - - private static final long serialVersionUID = 8011973280114768008L; - private String name; - private int regulatorID; - private int segmentID; - private OdePosition3D anchorPosition; - private BigDecimal laneWidth; - private String directionality; - private boolean closedPath; - private String direction; - private String description; - private Path path; - private Geometry geometry; - private OldRegion oldRegion; - - @EqualsAndHashCode(callSuper = false) - public static class OldRegion extends OdeObject { - - private static final long serialVersionUID = 1L; - private String direction; - private String extent; - private Area area; - - @EqualsAndHashCode(callSuper = false) - public static class ShapePointSet extends OdeObject { - - private static final long serialVersionUID = 1L; - private OdePosition3D anchor; - private BigDecimal laneWidth; - private int directionality; - private NodeListXY nodeList; - - public OdePosition3D getAnchor() { - return anchor; - } - - public void setAnchor(OdePosition3D anchor) { - this.anchor = anchor; - } - - public BigDecimal getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(BigDecimal laneWidth) { - this.laneWidth = laneWidth; - } - - public int getDirectionality() { - return directionality; - } - - public void setDirectionality(int directionality) { - this.directionality = directionality; - } - - public void setDirectionalityEnum(DirectionOfUseEnum directionalityEnum) { - this.directionality = directionalityEnum.ordinal(); - } - - public NodeListXY getNodeList() { - return nodeList; - } - - public void setNodeList(NodeListXY nodeList) { - this.nodeList = nodeList; - } - } - - @EqualsAndHashCode(callSuper = false) - public static class RegionPointSet extends OdeObject { - - private static final long serialVersionUID = 1L; - private OdePosition3D position; - private int scale; - private RegionList[] regionList; - - @EqualsAndHashCode(callSuper = false) - public static class RegionList extends OdeObject { - - private static final long serialVersionUID = -5307620155601900634L; - private BigDecimal xOffset; - private BigDecimal yOffset; - private BigDecimal zOffset; - - public BigDecimal getzOffset() { - return zOffset; - } - - public void setzOffset(BigDecimal zOffset) { - this.zOffset = zOffset; - } - - public BigDecimal getyOffset() { - return yOffset; - } - - public void setyOffset(BigDecimal yOffset) { - this.yOffset = yOffset; - } - - public BigDecimal getxOffset() { - return xOffset; - } - - public void setxOffset(BigDecimal xOffset) { - this.xOffset = xOffset; - } - } - - public RegionList[] getRegionList() { - return regionList; - } - - public void setRegionList(RegionList[] regionList) { - this.regionList = regionList; - } - - public int getScale() { - return scale; - } - - public void setScale(int scale) { - this.scale = scale; - } - - public OdePosition3D getPosition() { - return position; - } - - public void setPosition(OdePosition3D position) { - this.position = position; - } - } - - public Area getArea() { - return area; - } - - public void setArea(Area area) { - this.area = area; - } - - public String getExtent() { - return extent; - } - - public void setExtent(String extent) { - this.extent = extent; - } - - public void setExtent(ExtentEnum extent) { - this.extent = extent.name(); - } - - public String getDirection() { - return direction; - } - - public void setDirection(String direction) { - this.direction = direction; - } - } - - public static class Geometry extends OdeObject { - - private static final long serialVersionUID = -7664796173893464468L; - private String direction; - private int extent; - private BigDecimal laneWidth; - private Circle circle; - - public Circle getCircle() { - return circle; - } - - public void setCircle(Circle circle) { - this.circle = circle; - } - - public BigDecimal getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(BigDecimal laneWidth) { - this.laneWidth = laneWidth; - } - - public int getExtent() { - return extent; - } - - public void setExtent(int extent) { - this.extent = extent; - } - public String getDirection() { - return direction; - } - - public void setDirection(String direction) { - this.direction = direction; - } - } - - @EqualsAndHashCode(callSuper = false) - public static class Circle extends OdeObject { - - private static final long serialVersionUID = -8156052898034497978L; - private OdePosition3D position; - private OdePosition3D center; - private int radius; - private String units; - - public String getUnits() { - return units; - } - - public void setUnits(String units) { - this.units = units; - } - - public void setUnits(DistanceUnitsEnum units) { - this.units = units.name(); - } - - public int getRadius() { - return radius; - } - - public void setRadius(int radius) { - this.radius = radius; - } - - public OdePosition3D getPosition() { - return position; - } - - public void setPosition(OdePosition3D position) { - this.position = position; - } - - public OdePosition3D getCenter() { - return center; - } - - public void setCenter(OdePosition3D center) { - this.center = center; - } - } - - @EqualsAndHashCode(callSuper = false) - public static class Path extends OdeObject { - - private static final long serialVersionUID = 3293758823626661508L; - private int scale; - private String type; - private NodeXY[] nodes; - private ComputedLane computedLane; - - public ComputedLane getComputedLane() { - return computedLane; - } - - public void setComputedLane(ComputedLane computedLane) { - this.computedLane = computedLane; - } - - public NodeXY[] getNodes() { - return nodes; - } - - public void setNodes(NodeXY[] nodes) { - this.nodes = nodes; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public int getScale() { - return scale; - } - - public void setScale(int scale) { - this.scale = scale; - } - } - - public OldRegion getOldRegion() { - return oldRegion; - } + } - public void setOldRegion(OldRegion oldRegion) { - this.oldRegion = oldRegion; - } - - public Geometry getGeometry() { - return geometry; - } - - public void setGeometry(Geometry geometry) { - this.geometry = geometry; - } - - public Path getPath() { - return path; - } - - public void setPath(Path path) { - this.path = path; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getDirection() { - return direction; - } - - public void setDirection(String direction) { - this.direction = direction; - } - - public boolean isClosedPath() { - return closedPath; - } - - public void setClosedPath(boolean closedPath) { - this.closedPath = closedPath; - } - - public String getDirectionality() { - return directionality; - } - - public void setDirectionality(String directionality) { - this.directionality = directionality; - } + @EqualsAndHashCode(callSuper = false) + public static class RoadSignID extends OdeObject { - public BigDecimal getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(BigDecimal laneWidth) { - this.laneWidth = laneWidth; - } - - public OdePosition3D getAnchorPosition() { - return anchorPosition; - } - - public void setAnchorPosition(OdePosition3D anchorPosition) { - this.anchorPosition = anchorPosition; - } - - public int getSegmentID() { - return segmentID; - } - - public void setSegmentID(int segmentID) { - this.segmentID = segmentID; - } - - public int getRegulatorID() { - return regulatorID; - } - - public void setRegulatorID(int regulatorID) { - this.regulatorID = regulatorID; - } - - public String getName() { - return name; - } + private static final long serialVersionUID = 1L; - public void setName(String name) { - this.name = name; - } + private OdePosition3D position; + private String viewAngle; + private MutcdCode.MutcdCodeEnum mutcdCode; + private String crc; + public OdePosition3D getPosition() { + return position; } - @EqualsAndHashCode(callSuper = false) - public static class RoadSignID extends OdeObject { - - private static final long serialVersionUID = 1L; - - private OdePosition3D position; - private String viewAngle; - private MutcdCode.MutcdCodeEnum mutcdCode; - private String crc; - - public OdePosition3D getPosition() { - return position; - } - - public void setPosition(OdePosition3D position) { - this.position = position; - } - - public String getViewAngle() { - return viewAngle; - } - - public void setViewAngle(String viewAngle) { - this.viewAngle = viewAngle; - } - - public MutcdCode.MutcdCodeEnum getMutcdCode() { - return mutcdCode; - } + public void setPosition(OdePosition3D position) { + this.position = position; + } - public void setMutcdCode(MutcdCode.MutcdCodeEnum mutcdCode) { - this.mutcdCode = mutcdCode; - } + public String getViewAngle() { + return viewAngle; + } - public String getCrc() { - return crc; - } + public void setViewAngle(String viewAngle) { + this.viewAngle = viewAngle; + } - public void setCrc(String crc) { - this.crc = crc; - } + public MutcdCode.MutcdCodeEnum getMutcdCode() { + return mutcdCode; } - @EqualsAndHashCode(callSuper = false) - public static class MsgId extends Asn1Object { - private static final long serialVersionUID = 1L; + public void setMutcdCode(MutcdCode.MutcdCodeEnum mutcdCode) { + this.mutcdCode = mutcdCode; + } - private RoadSignID roadSignID; - private String furtherInfoID; + public String getCrc() { + return crc; + } - public RoadSignID getRoadSignID() { - return roadSignID; - } + public void setCrc(String crc) { + this.crc = crc; + } + } - public void setRoadSignID(RoadSignID roadSignID) { - this.roadSignID = roadSignID; - } + @EqualsAndHashCode(callSuper = false) + public static class MsgId extends Asn1Object { + private static final long serialVersionUID = 1L; - public String getFurtherInfoID() { - return furtherInfoID; - } + private RoadSignID roadSignID; + private String furtherInfoID; - public void setFurtherInfoID(String furtherInfoID) { - this.furtherInfoID = furtherInfoID; - } + public RoadSignID getRoadSignID() { + return roadSignID; } - public MsgId getMsgId() { - return msgId; + public void setRoadSignID(RoadSignID roadSignID) { + this.roadSignID = roadSignID; } - public void setMsgId(MsgId msgId) { - this.msgId = msgId; + public String getFurtherInfoID() { + return furtherInfoID; } - public String getUrl() { - return url; + public void setFurtherInfoID(String furtherInfoID) { + this.furtherInfoID = furtherInfoID; } + } - public void setUrl(String url) { - this.url = url; - } + public MsgId getMsgId() { + return msgId; + } - public String[] getItems() { - return items; - } + public void setMsgId(MsgId msgId) { + this.msgId = msgId; + } - public void setItems(String[] items) { - this.items = items; - } + public String getUrl() { + return url; + } - public String getContent() { - return content; - } + public void setUrl(String url) { + this.url = url; + } - public void setContent(String content) { - this.content = content; - } + public String[] getItems() { + return items; + } - public Region[] getRegions() { - return regions; - } + public void setItems(String[] items) { + this.items = items; + } - public void setRegions(Region[] regions) { - this.regions = regions; - } + public String getContent() { + return content; + } - public int getPriority() { - return priority; - } + public void setContent(String content) { + this.content = content; + } - public void setPriority(int priority) { - this.priority = priority; - } + public Region[] getRegions() { + return regions; + } - public int getDurationTime() { - return durationTime; - } + public void setRegions(Region[] regions) { + this.regions = regions; + } - public void setDurationTime(int durationTime) { - this.durationTime = durationTime; - } + public int getPriority() { + return priority; + } - public String getStartDateTime() { - return startDateTime; - } + public void setPriority(int priority) { + this.priority = priority; + } - public void setStartDateTime(String startDateTime) { - this.startDateTime = startDateTime; - } + public int getDurationTime() { + return durationTime; + } - public FrameType.TravelerInfoType getFrameType() { - return frameType; - } + public void setDurationTime(int durationTime) { + this.durationTime = durationTime; + } - public void setFrameType(FrameType.TravelerInfoType frameType) { - this.frameType = frameType; - } + public String getStartDateTime() { + return startDateTime; + } - public short getDoNotUse1() { - return doNotUse1; - } + public void setStartDateTime(String startDateTime) { + this.startDateTime = startDateTime; + } - public void setDoNotUse1(short doNotUse1) { - this.doNotUse1 = doNotUse1; - } + public FrameType.TravelerInfoType getFrameType() { + return frameType; + } - public short getDoNotUse2() { - return doNotUse2; - } + public void setFrameType(FrameType.TravelerInfoType frameType) { + this.frameType = frameType; + } - public void setDoNotUse2(short doNotUse2) { - this.doNotUse2 = doNotUse2; - } + public short getDoNotUse1() { + return doNotUse1; + } - public short getDoNotUse3() { - return doNotUse3; - } + public void setDoNotUse1(short doNotUse1) { + this.doNotUse1 = doNotUse1; + } - public void setDoNotUse3(short doNotUse3) { - this.doNotUse3 = doNotUse3; - } + public short getDoNotUse2() { + return doNotUse2; + } - public short getDoNotUse4() { - return doNotUse4; - } + public void setDoNotUse2(short doNotUse2) { + this.doNotUse2 = doNotUse2; + } - public void setDoNotUse4(short doNotUse4) { - this.doNotUse4 = doNotUse4; - } + public short getDoNotUse3() { + return doNotUse3; + } + + public void setDoNotUse3(short doNotUse3) { + this.doNotUse3 = doNotUse3; + } + + public short getDoNotUse4() { + return doNotUse4; + } + + public void setDoNotUse4(short doNotUse4) { + this.doNotUse4 = doNotUse4; + } - } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index fc116eabb..b25f87a7c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.builders; import java.math.BigDecimal; @@ -40,1081 +41,1114 @@ public class TravelerMessageFromHumanToAsnConverter { - private static final String SPEED = "speed"; - private static final String TYPE = "type"; - private static final String ATTRIBUTES = "attributes"; - public static final String TRAVELER_INFORMATION = "TravelerInformation"; - private static final String EXTENT = "extent"; - private static final String UNITS = "units"; - private static final String DIRECTIONALITY = "directionality"; - private static final String CENTER = "center"; - private static final String NODE_LAT = "nodeLat"; - private static final String NODE_LONG = "nodeLong"; - private static final String Y = "y"; - private static final String X = "x"; - private static final String NODE_LAT_LON = "node-LatLon"; - private static final String LON = "lon"; - private static final String LAT = "lat"; - private static final String NODE_XY = "node-XY"; - private static final String NODE_XY2 = "NodeXY"; - private static final String COMPUTED = "computed"; - private static final String SPEED_LIMITS = "speedLimits"; - private static final String LANE_ANGLE = "laneAngle"; - private static final String LANE_CROWN_POINT_RIGHT = "laneCrownPointRight"; - private static final String LANE_CROWN_POINT_LEFT = "laneCrownPointLeft"; - private static final String LANE_CROWN_POINT_CENTER = "laneCrownPointCenter"; - private static final String D_ELEVATION = "dElevation"; - private static final String D_WIDTH = "dWidth"; - private static final String DATA = "data"; - private static final String OFFSET_X_AXIS = "offsetXaxis"; - private static final String OFFSET_Y_AXIS = "offsetYaxis"; - private static final String ROTATE_XY = "rotateXY"; - private static final String SCALE_X_AXIS = "scaleXaxis"; - private static final String SCALE_Y_AXIS = "scaleYaxis"; - private static final String NODE_LIST = "nodeList"; - private static final String REGION_POINT_SET = "regionPointSet"; - private static final String CIRCLE = "circle"; - private static final String SHAPE_POINT_SET = "shapePointSet"; - private static final String DELTA = "delta"; - private static final String OFFSET = "offset"; - private static final String NODES = "nodes"; - private static final String XY = "xy"; - private static final String LL = "ll"; - private static final String OLD_REGION = "oldRegion"; - private static final String GEOMETRY = "geometry"; - private static final String PATH = "path"; - private static final String DESCRIPTION = "description"; - private static final String CLOSED_PATH = "closedPath"; - private static final String ANCHOR = "anchor"; - private static final String ID = "id"; - private static final String REGION = "region"; - private static final String LANE_WIDTH = "laneWidth"; - private static final String ANCHOR_POSITION = "anchorPosition"; - private static final String REGULATOR_ID = "regulatorID"; - private static final String SEGMENT_ID = "segmentID"; - private static final String POSITION = "position"; - private static final String TEXT = "text"; - private static final String ITIS = "itis"; - private static final String ITEM = "item"; - private static final String START_DATE_TIME = "startDateTime"; - private static final String DURATON_TIME_MISSPELLED = "duratonTime"; // J2735 2016 Misspelling - private static final String SSP_TIM_RIGHTS = "sspTimRights"; // used in J2735 2016 - private static final String NOT_USED = "notUsed"; // used in J2735 2020 - private static final String SSP_LOCATION_RIGHTS = "sspLocationRights"; // used in J2735 2016 - private static final String NOT_USED_1 = "notUsed1"; // used in J2735 2020 - private static final String SSP_MSG_TYPES = "sspMsgTypes"; // used previously - private static final String SSP_MSG_RIGHTS_1 = "sspMsgRights1"; // used in J2735 2016 - private static final String NOT_USED_2 = "notUsed2"; // used in J2735 2020 - private static final String SSP_MSG_CONTENT = "sspMsgContent"; // used previously - private static final String SSP_MSG_RIGHTS_2 = "sspMsgRights2"; // used in J2735 2016 - private static final String NOT_USED_3 = "notUsed3"; // used in J2735 2020 - private static final String DATAFRAMES = "dataframes"; - private static final String TIME_STAMP = "timeStamp"; - public static final String GEOGRAPHICAL_PATH_STRING = "GeographicalPath"; - public static final String REGIONS_STRING = "regions"; - public static final String TRAVELER_DATA_FRAME_STRING = "TravelerDataFrame"; - public static final String DATA_FRAMES_STRING = "dataFrames"; - public static final String SEQUENCE_STRING = "SEQUENCE"; - public static final String TCONTENT_STRING = "tcontent"; - // JSON cannot have empty fields like XML, so the XML must be modified by - // removing all flag field values - public static final String EMPTY_FIELD_FLAG = "EMPTY_TAG"; - public static final String BOOLEAN_OBJECT_TRUE = "BOOLEAN_OBJECT_TRUE"; - public static final String BOOLEAN_OBJECT_FALSE = "BOOLEAN_OBJECT_FALSE"; - - private static final Logger logger = LoggerFactory.getLogger(TravelerMessageFromHumanToAsnConverter.class); - - private TravelerMessageFromHumanToAsnConverter() { - super(); - } - - /** - * Converts a JsonNode representing an OdeTravelerInputData object to a format that can be encoded by the asn1_codec submodule. - * @param tid TravelerInputData object serialized as a JsonNode - * @throws JsonUtilsException if there is an issue converting the JsonNode - * @throws IllegalArgumentException if the JsonNode contains old fields that are no longer used - */ - public static void convertTravelerInputDataToEncodableTim(JsonNode tid) throws JsonUtilsException { - // msgCnt MsgCount, - // timeStamp MinuteOfTheYear OPTIONAL - // packetID UniqueMSGID OPTIONAL - // urlB URL-Base OPTIONAL - // dataFrames TravelerDataFrameList - - // Cast to ObjectNode to allow manipulation in place - ObjectNode timDataObjectNode = (ObjectNode) tid.get("tim"); - - // timeStamp is optional - if (timDataObjectNode.get(TIME_STAMP) != null) { - timDataObjectNode.put(TIME_STAMP, - translateISOTimeStampToMinuteOfYear(timDataObjectNode.get(TIME_STAMP).asText())); - } - - // urlB is optional but does not need replacement - - // dataFrames are required - timDataObjectNode.set(DATA_FRAMES_STRING, transformDataFrames(timDataObjectNode.get(DATAFRAMES))); - timDataObjectNode.remove(DATAFRAMES); - } - - public static ObjectNode transformDataFrames(JsonNode dataFrames) throws JsonUtilsException { - - if (dataFrames == null) { - return JsonUtils.newNode(); - } - - ArrayNode replacedDataFrames = JsonUtils.newNode().arrayNode(); - if (dataFrames.isArray()) { - Iterator dataFramesIter = dataFrames.elements(); - - while (dataFramesIter.hasNext()) { - ObjectNode oldFrame = (ObjectNode) dataFramesIter.next(); - replaceDataFrame(oldFrame); - // wrap each data frame inside a TravelerDataFrame - replacedDataFrames.add(oldFrame); - } - } - - return JsonUtils.newObjectNode(TRAVELER_DATA_FRAME_STRING, replacedDataFrames); - } - - public static void replaceDataFrame(ObjectNode dataFrame) throws JsonUtilsException { - - // INPUT - ////// - // "dataframes": [ - // - // "startDateTime": "2017-08-02T22:25:00.000Z", - // "durationTime": 1, - // "frameType": "1", - // "sspTimRights": "0", - // "msgID": "RoadSignID", - // "position": { - // "latitude": "41.678473", - // "longitude": "-108.782775", - // "elevation": "917.1432" - // }, - // "viewAngle": "1010101010101010", - // "mutcd": "5", - // "crc": "0000000000000000", - // "priority": "0", - // "sspLocationRights": "3", - // "regions": [] - // "sspMsgTypes": "2", - // "sspMsgContent": "3", - // "content": "advisory", - // "items": [ - // "513" - // ], - // "url": "null" - // - // ] - - /// OUTPUT: - ////// - // - // - // 2017 - // 308065 - // - // - - // set frameType value - dataFrame.set("frameType", JsonUtils.newNode().put(dataFrame.get("frameType").asText(), EMPTY_FIELD_FLAG)); - - ensureComplianceWithJ2735Revision2024(dataFrame); - - // priority does not need replacement - - // url does not need replacement - - replaceDataFrameTimestamp(dataFrame); - - // replace the geographical path regions - dataFrame.set(REGIONS_STRING, transformRegions(dataFrame.get(REGIONS_STRING))); - // replace content - replaceContent(dataFrame); - - // replace the msgID and relevant fields - replaceMsgId(dataFrame); - } - - public static long translateISOTimeStampToMinuteOfYear(String isoTime) { - int startYear = 0; - int startMinute = 527040; - try { - ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(isoTime); - startYear = zDateTime.getYear(); - startMinute = (int) Duration.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), zDateTime) - .toMinutes(); - } catch (Exception e) { // NOSONAR - logger.error("Failed to parse datetime {}, defaulting to unknown value {}", isoTime, startMinute); + private static final String SPEED = "speed"; + private static final String TYPE = "type"; + private static final String ATTRIBUTES = "attributes"; + public static final String TRAVELER_INFORMATION = "TravelerInformation"; + private static final String EXTENT = "extent"; + private static final String UNITS = "units"; + private static final String DIRECTIONALITY = "directionality"; + private static final String CENTER = "center"; + private static final String NODE_LAT = "nodeLat"; + private static final String NODE_LONG = "nodeLong"; + private static final String Y = "y"; + private static final String X = "x"; + private static final String NODE_LAT_LON = "node-LatLon"; + private static final String LON = "lon"; + private static final String LAT = "lat"; + private static final String NODE_XY = "node-XY"; + private static final String NODE_XY2 = "NodeXY"; + private static final String COMPUTED = "computed"; + private static final String SPEED_LIMITS = "speedLimits"; + private static final String LANE_ANGLE = "laneAngle"; + private static final String LANE_CROWN_POINT_RIGHT = "laneCrownPointRight"; + private static final String LANE_CROWN_POINT_LEFT = "laneCrownPointLeft"; + private static final String LANE_CROWN_POINT_CENTER = "laneCrownPointCenter"; + private static final String D_ELEVATION = "dElevation"; + private static final String D_WIDTH = "dWidth"; + private static final String DATA = "data"; + private static final String OFFSET_X_AXIS = "offsetXaxis"; + private static final String OFFSET_Y_AXIS = "offsetYaxis"; + private static final String ROTATE_XY = "rotateXY"; + private static final String SCALE_X_AXIS = "scaleXaxis"; + private static final String SCALE_Y_AXIS = "scaleYaxis"; + private static final String NODE_LIST = "nodeList"; + private static final String REGION_POINT_SET = "regionPointSet"; + private static final String CIRCLE = "circle"; + private static final String SHAPE_POINT_SET = "shapePointSet"; + private static final String DELTA = "delta"; + private static final String OFFSET = "offset"; + private static final String NODES = "nodes"; + private static final String XY = "xy"; + private static final String LL = "ll"; + private static final String OLD_REGION = "oldRegion"; + private static final String GEOMETRY = "geometry"; + private static final String PATH = "path"; + private static final String DESCRIPTION = "description"; + private static final String CLOSED_PATH = "closedPath"; + private static final String ANCHOR = "anchor"; + private static final String ID = "id"; + private static final String REGION = "region"; + private static final String LANE_WIDTH = "laneWidth"; + private static final String ANCHOR_POSITION = "anchorPosition"; + private static final String REGULATOR_ID = "regulatorID"; + private static final String SEGMENT_ID = "segmentID"; + private static final String POSITION = "position"; + private static final String TEXT = "text"; + private static final String ITIS = "itis"; + private static final String ITEM = "item"; + private static final String START_DATE_TIME = "startDateTime"; + private static final String DURATON_TIME_MISSPELLED = "duratonTime"; // J2735 2016 Misspelling + private static final String SSP_TIM_RIGHTS = "sspTimRights"; // used in J2735 2016 + private static final String NOT_USED = "notUsed"; // used in J2735 2020 + private static final String SSP_LOCATION_RIGHTS = "sspLocationRights"; // used in J2735 2016 + private static final String NOT_USED_1 = "notUsed1"; // used in J2735 2020 + private static final String SSP_MSG_TYPES = "sspMsgTypes"; // used previously + private static final String SSP_MSG_RIGHTS_1 = "sspMsgRights1"; // used in J2735 2016 + private static final String NOT_USED_2 = "notUsed2"; // used in J2735 2020 + private static final String SSP_MSG_CONTENT = "sspMsgContent"; // used previously + private static final String SSP_MSG_RIGHTS_2 = "sspMsgRights2"; // used in J2735 2016 + private static final String NOT_USED_3 = "notUsed3"; // used in J2735 2020 + private static final String DATAFRAMES = "dataframes"; + private static final String TIME_STAMP = "timeStamp"; + public static final String GEOGRAPHICAL_PATH_STRING = "GeographicalPath"; + public static final String REGIONS_STRING = "regions"; + public static final String TRAVELER_DATA_FRAME_STRING = "TravelerDataFrame"; + public static final String DATA_FRAMES_STRING = "dataFrames"; + public static final String SEQUENCE_STRING = "SEQUENCE"; + public static final String TCONTENT_STRING = "tcontent"; + // JSON cannot have empty fields like XML, so the XML must be modified by + // removing all flag field values + public static final String EMPTY_FIELD_FLAG = "EMPTY_TAG"; + public static final String BOOLEAN_OBJECT_TRUE = "BOOLEAN_OBJECT_TRUE"; + public static final String BOOLEAN_OBJECT_FALSE = "BOOLEAN_OBJECT_FALSE"; + + private static final Logger logger = + LoggerFactory.getLogger(TravelerMessageFromHumanToAsnConverter.class); + + private TravelerMessageFromHumanToAsnConverter() { + super(); + } + + /** + * Converts a JsonNode representing an OdeTravelerInputData object to a format that can be encoded by the asn1_codec submodule. + * + * @param tid TravelerInputData object serialized as a JsonNode + * @throws JsonUtilsException if there is an issue converting the JsonNode + * @throws IllegalArgumentException if the JsonNode contains old fields that are no longer used + */ + public static void convertTravelerInputDataToEncodableTim(JsonNode tid) + throws JsonUtilsException { + // msgCnt MsgCount, + // timeStamp MinuteOfTheYear OPTIONAL + // packetID UniqueMSGID OPTIONAL + // urlB URL-Base OPTIONAL + // dataFrames TravelerDataFrameList + + // Cast to ObjectNode to allow manipulation in place + ObjectNode timDataObjectNode = (ObjectNode) tid.get("tim"); + + // timeStamp is optional + if (timDataObjectNode.get(TIME_STAMP) != null) { + timDataObjectNode.put(TIME_STAMP, + translateISOTimeStampToMinuteOfYear(timDataObjectNode.get(TIME_STAMP).asText())); + } + + // urlB is optional but does not need replacement + + // dataFrames are required + timDataObjectNode.set(DATA_FRAMES_STRING, + transformDataFrames(timDataObjectNode.get(DATAFRAMES))); + timDataObjectNode.remove(DATAFRAMES); + } + + public static ObjectNode transformDataFrames(JsonNode dataFrames) throws JsonUtilsException { + + if (dataFrames == null) { + return JsonUtils.newNode(); + } + + ArrayNode replacedDataFrames = JsonUtils.newNode().arrayNode(); + if (dataFrames.isArray()) { + Iterator dataFramesIter = dataFrames.elements(); + + while (dataFramesIter.hasNext()) { + ObjectNode oldFrame = (ObjectNode) dataFramesIter.next(); + replaceDataFrame(oldFrame); + // wrap each data frame inside a TravelerDataFrame + replacedDataFrames.add(oldFrame); } - - return startMinute; - } - - public static void replaceDataFrameTimestamp(ObjectNode dataFrame) { - - // EXPECTED INPUT: - // "timeStamp": "2017-08-03T22:25:36.297Z" - - // EXPECTED OUTPUT: - // 2017 - // 308065 - - // unknown year value = 0 - // unknown minuteofyear = 527040 - int startYear = 0; - int startMinute = 527040; - String startDateTime = dataFrame.get(START_DATE_TIME).asText(); - try { - ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(startDateTime); - startYear = zDateTime.getYear(); - startMinute = (int) ChronoUnit.MINUTES.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), - zDateTime); - } catch (Exception e) { - logger.error("Failed to startDateTime {}, defaulting to unknown value {}.", startDateTime, startMinute); - } - - dataFrame.put("startYear", startYear); - dataFrame.put("startTime", startMinute); - dataFrame.remove(START_DATE_TIME); - } - - public static void replaceContent(ObjectNode dataFrame) { - - // EXPECTED OUTPUT: - /////// - // - // - // - // - // 513 - // - // - // - // - - // EXPECTED INPUT: - //////// - // "content": "advisory", - // "items":["513", "Text you need to send", "'1234567'", "255"]}, - - // step 1, reformat item list - ArrayNode items = (ArrayNode) dataFrame.get("items"); - ArrayNode newItems = JsonUtils.newNode().arrayNode(); - if (items.isArray()) { - // take the array of ITIScodesAndText items and transform it into - // schema-appropriate array - - Iterator itemsIter = items.elements(); - - while (itemsIter.hasNext()) { - JsonNode curItem = itemsIter.next(); - newItems.add(buildItem(curItem.asText())); - } - } - - JsonNode sequence = JsonUtils.newNode().set(SEQUENCE_STRING, newItems); - - dataFrame.remove("items"); - - // step 2, set the content CHOICE - String replacedContentName = dataFrame.get("content").asText(); - if (replacedContentName.equals("Advisory")) - replacedContentName = "advisory"; - - // The following field is called "content" but this results in a - // failed conversion to XML - // see @us.dot.its.jpo.ode.traveler.TimController.publish - dataFrame.set(TCONTENT_STRING, JsonUtils.newNode().set(replacedContentName, sequence)); - dataFrame.remove("content"); - } - - public static JsonNode buildItem(String itemStr) { - JsonNode item = null; - // check to see if it is a itis code or text - try { - item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(ITIS, Integer.valueOf(itemStr))); - // it's a number, so create "itis" code - } catch (NumberFormatException e) { - // it's a number, so create "text" - if (itemStr.startsWith("'")) { - item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(TEXT, itemStr.substring(1))); - } else { - item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(TEXT, itemStr)); - } - } - - return item; - } - - public static void replaceMsgId(ObjectNode dataFrame) { - - // - // - // - // 416784730 - // -1087827750 - // 9171 - // - // 0101010101010100 - // - // - // - // 0000 - // - // - - JsonNode msgId = dataFrame.get("msgId"); - if (msgId != null) { - ObjectNode roadSignID = (ObjectNode) msgId.get("roadSignID"); - if (roadSignID != null) { - - DsrcPosition3D position = Position3DBuilder - .dsrcPosition3D(Position3DBuilder.odePosition3D(roadSignID.get(POSITION))); - - roadSignID.putPOJO(POSITION, position); - - // mutcdCode is optional - JsonNode mutcdNode = roadSignID.get("mutcdCode"); - if (mutcdNode != null) { - roadSignID.set("mutcdCode", JsonUtils.newNode().put(mutcdNode.asText(), EMPTY_FIELD_FLAG)); - } - } - } - } - - public static ObjectNode transformRegions(JsonNode regions) throws JsonUtilsException { - ArrayNode replacedRegions = JsonUtils.newNode().arrayNode(); - - if (regions.isArray()) { - Iterator regionsIter = regions.elements(); - - while (regionsIter.hasNext()) { - JsonNode curRegion = regionsIter.next(); - replaceRegion((ObjectNode) curRegion); - replacedRegions.add(curRegion); - } - } - - return JsonUtils.newObjectNode(GEOGRAPHICAL_PATH_STRING, replacedRegions); - } - - public static void replaceRegion(ObjectNode region) throws JsonUtilsException { - - //// EXPECTED INPUT: - // "name": "Testing TIM", - // "regulatorID": "0", - // "segmentID": "33", - // "anchorPosition": - // "latitude": "41.2500807", - // "longitude": "-111.0093847", - // "elevation": "2020.6969900289998" - // , - // "laneWidth": "7", - // "directionality": "3", - // "closedPath": "false", - // "description": "path", - // "path": {}, - // "direction": "0000000000001010" - // - - //// EXPECTED OUTPUT: - // - // .Testing TIM - // . - // ..0 - // ..33 - // . - // . - // ..412500807 - // ..-1110093847 - // ..20206 - // . - // .700 - // . - // .. - // . - // . - // .. - // . - // .0000000000010100 - // . - // . - // - - // name does not need to be replaced - - // id optional, consists of segmentID (required) - // and regulatorID (optional) - JsonNode segmentID = region.get(SEGMENT_ID); - if (segmentID != null) { - ObjectNode id = JsonUtils.newNode().put(ID, segmentID.asInt()); - JsonNode regulatorID = region.get(REGULATOR_ID); - if (regulatorID != null) { - id.put(REGION, regulatorID.asInt()); - } - region.set(ID, id); - } - // replace regulatorID and segmentID with id - ObjectNode id = JsonUtils.newNode().put(REGION, region.get(REGULATOR_ID).asInt()).put(ID, - region.get(SEGMENT_ID).asInt()); - - region.set(ID, id); - region.remove(REGULATOR_ID); - region.remove(SEGMENT_ID); - - // anchorPosition --> anchor (optional) - JsonNode anchorPos = region.get(ANCHOR_POSITION); - if (anchorPos != null) { - region.set(ANCHOR, JsonUtils.toObjectNode(Position3DBuilder - .dsrcPosition3D(Position3DBuilder.odePosition3D(region.get(ANCHOR_POSITION))).toJson())); - region.remove(ANCHOR_POSITION); + } + + return JsonUtils.newObjectNode(TRAVELER_DATA_FRAME_STRING, replacedDataFrames); + } + + public static void replaceDataFrame(ObjectNode dataFrame) throws JsonUtilsException { + + // INPUT + ////// + // "dataframes": [ + // + // "startDateTime": "2017-08-02T22:25:00.000Z", + // "durationTime": 1, + // "frameType": "1", + // "sspTimRights": "0", + // "msgID": "RoadSignID", + // "position": { + // "latitude": "41.678473", + // "longitude": "-108.782775", + // "elevation": "917.1432" + // }, + // "viewAngle": "1010101010101010", + // "mutcd": "5", + // "crc": "0000000000000000", + // "priority": "0", + // "sspLocationRights": "3", + // "regions": [] + // "sspMsgTypes": "2", + // "sspMsgContent": "3", + // "content": "advisory", + // "items": [ + // "513" + // ], + // "url": "null" + // + // ] + + /// OUTPUT: + ////// + // + // + // 2017 + // 308065 + // + // + + // set frameType value + dataFrame.set("frameType", + JsonUtils.newNode().put(dataFrame.get("frameType").asText(), EMPTY_FIELD_FLAG)); + + ensureComplianceWithJ2735Revision2024(dataFrame); + + // priority does not need replacement + + // url does not need replacement + + replaceDataFrameTimestamp(dataFrame); + + // replace the geographical path regions + dataFrame.set(REGIONS_STRING, transformRegions(dataFrame.get(REGIONS_STRING))); + // replace content + replaceContent(dataFrame); + + // replace the msgID and relevant fields + replaceMsgId(dataFrame); + } + + public static long translateISOTimeStampToMinuteOfYear(String isoTime) { + int startYear = 0; + int startMinute = 527040; + try { + ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(isoTime); + startYear = zDateTime.getYear(); + startMinute = + (int) Duration.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), zDateTime) + .toMinutes(); + } catch (Exception e) { // NOSONAR + logger.error("Failed to parse datetime {}, defaulting to unknown value {}", isoTime, + startMinute); + } + + return startMinute; + } + + public static void replaceDataFrameTimestamp(ObjectNode dataFrame) { + + // EXPECTED INPUT: + // "timeStamp": "2017-08-03T22:25:36.297Z" + + // EXPECTED OUTPUT: + // 2017 + // 308065 + + // unknown year value = 0 + // unknown minuteofyear = 527040 + int startYear = 0; + int startMinute = 527040; + String startDateTime = dataFrame.get(START_DATE_TIME).asText(); + try { + ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(startDateTime); + startYear = zDateTime.getYear(); + startMinute = + (int) ChronoUnit.MINUTES.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), + zDateTime); + } catch (Exception e) { + logger.error("Failed to startDateTime {}, defaulting to unknown value {}.", startDateTime, + startMinute); + } + + dataFrame.put("startYear", startYear); + dataFrame.put("startTime", startMinute); + dataFrame.remove(START_DATE_TIME); + } + + public static void replaceContent(ObjectNode dataFrame) { + + // EXPECTED OUTPUT: + /////// + // + // + // + // + // 513 + // + // + // + // + + // EXPECTED INPUT: + //////// + // "content": "advisory", + // "items":["513", "Text you need to send", "'1234567'", "255"]}, + + // step 1, reformat item list + ArrayNode items = (ArrayNode) dataFrame.get("items"); + ArrayNode newItems = JsonUtils.newNode().arrayNode(); + if (items.isArray()) { + // take the array of ITIScodesAndText items and transform it into + // schema-appropriate array + + Iterator itemsIter = items.elements(); + + while (itemsIter.hasNext()) { + JsonNode curItem = itemsIter.next(); + newItems.add(buildItem(curItem.asText())); } - - // lane width (optional) - JsonNode laneWidth = region.get(LANE_WIDTH); - if (laneWidth != null) { - region.put(LANE_WIDTH, LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(laneWidth))); - } - - // directionality (optional) - if (region.has(DIRECTIONALITY)) { - JsonNode directionality = region.get(DIRECTIONALITY); - String enumString = CommonUtils.enumToString(DirectionOfUseEnum.class, directionality.asText()); - if (enumString != null) { - region.set(DIRECTIONALITY, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); - } - } - - // closed path (optional) - JsonNode closedPath = region.get(CLOSED_PATH); - if (closedPath != null) { - region.put(CLOSED_PATH, (closedPath.asBoolean() ? BOOLEAN_OBJECT_TRUE : BOOLEAN_OBJECT_FALSE)); - } - - // description (optional) - JsonNode descriptionNode = region.get(DESCRIPTION); - if (descriptionNode != null) { - String descriptionType = descriptionNode.asText(); - if (PATH.equals(descriptionType)) { - ObjectNode pathNode = (ObjectNode) region.get(PATH); - replacePath(pathNode); - region.set(DESCRIPTION, JsonUtils.newNode().set(PATH, pathNode)); - } else if (GEOMETRY.equals(descriptionType)) { - ObjectNode newGeometry = (ObjectNode) region.get(GEOMETRY); - replaceGeometry(newGeometry); - region.set(DESCRIPTION, JsonUtils.newNode().set(GEOMETRY, newGeometry)); - } else if (OLD_REGION.equals(descriptionType)) { - ObjectNode newOldRegion = (ObjectNode) region.get(OLD_REGION); - replaceOldRegion(newOldRegion); - region.set(DESCRIPTION, JsonUtils.newNode().set(OLD_REGION, newOldRegion)); - } - region.remove(descriptionType); - } - } - - private static void replacePath(ObjectNode pathNode) { - - //// EXPECTED INPUT: - // "path": - // "scale": "0", - // "type": "ll", - // "nodes": [] - // - - //// EXPECTED OUTPUT: - // - // .0 - // . - // .. - // ... - // ... - // .. - // . - // - - // zoom does not need to be replaced - String nodeType = pathNode.get(TYPE).asText(); - JsonNode nodes = pathNode.get(NODES); - JsonNode nodeList; - if (LL.equals(nodeType)) { - nodeList = JsonUtils.newNode().set("NodeLL", transformNodeSetLL(nodes)); - pathNode.set(OFFSET, JsonUtils.newNode().set(LL, JsonUtils.newNode().set(NODES, nodeList))); - } else if (XY.equals(nodeType)) { - nodeList = JsonUtils.newNode().set(NODE_XY2, transformNodeSetXY(nodes)); - pathNode.set(OFFSET, JsonUtils.newNode().set(XY, JsonUtils.newNode().set(NODES, nodeList))); - } - pathNode.remove(NODES); - pathNode.remove(TYPE); - - } - - private static ArrayNode transformNodeSetLL(JsonNode nodes) { - - //// EXPECTED INPUT: - // "nodes": [] - - // EXPECTED OUTPUT: - // - // . - // . - // . - // . - // - - ArrayNode outputNodeList = JsonUtils.newNode().arrayNode(); - - if (nodes.isArray()) { - Iterator nodeListIter = nodes.elements(); - - while (nodeListIter.hasNext()) { - JsonNode inputNode = nodeListIter.next(); - outputNodeList.add(transformNodeLL(inputNode)); - } - } - - return outputNodeList; - } - - private static ObjectNode transformNodeLL(JsonNode oldNode) { - - //// EXPECTED INPUT: - // - // "nodeLong": "0.0031024", - // "nodeLat": "0.0014506", - // "delta": "node-LL3" - // - - //// EXPECTED OUTPUT: - // - // . - // .. - // ...14506 - // ...31024 - // .. - // . - // - - BigDecimal latOffset = JsonUtils.decimalValue(oldNode.get(NODE_LAT)); - BigDecimal longOffset = JsonUtils.decimalValue(oldNode.get(NODE_LONG)); - JsonNode delta = oldNode.get(DELTA); - Long transformedLat = null; - Long transformedLong = null; - - ObjectNode innerNode = JsonUtils.newNode(); - ObjectNode deltaNode = (ObjectNode) JsonUtils.newNode().set(DELTA, innerNode); - ObjectNode latLong = JsonUtils.newNode(); - String deltaText = delta.asText(); - if (deltaText.startsWith("node-LL")) { - transformedLat = OffsetLLBuilder.offsetLL(latOffset); - transformedLong = OffsetLLBuilder.offsetLL(longOffset); - if (deltaText.equals("node-LL")) { - deltaText = nodeOffsetPointLL(transformedLat, transformedLong); - } - } else if (NODE_LAT_LON.equals(deltaText)) { - transformedLat = LatitudeBuilder.j2735Latitude(latOffset); - transformedLong = LongitudeBuilder.j2735Longitude(longOffset); - } - - innerNode.set(deltaText, latLong); - latLong.put(LAT, transformedLat).put(LON, transformedLong); - - return deltaNode; - } - - // -- Nodes with LL content Span at the equator when using a zoom of one: - // node-LL1 Node-LL-24B, -- within +- 22.634554 meters of last node - // node-LL2 Node-LL-28B, -- within +- 90.571389 meters of last node - // node-LL3 Node-LL-32B, -- within +- 362.31873 meters of last node - // node-LL4 Node-LL-36B, -- within +- 01.449308 Kmeters of last node - // node-LL5 Node-LL-44B, -- within +- 23.189096 Kmeters of last node - // node-LL6 Node-LL-48B, -- within +- 92.756481 Kmeters of last node - // node-LatLon Node-LLmD-64b, -- node is a full 32b Lat/Lon range - private static String nodeOffsetPointLL(long transformedLat, long transformedLon) { - long transformedLatabs = Math.abs(transformedLat); - long transformedLonabs = Math.abs(transformedLon); - if (((transformedLatabs & (-1 << 11)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 11)) == 0)) - && (transformedLonabs & (-1 << 11)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 11)) == 0))) { - // 11 bit value - return "node-LL1"; - } else if (((transformedLatabs & (-1 << 13)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 13)) == 0)) - && (transformedLonabs & (-1 << 13)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 13)) == 0))) { - // 13 bit value - return "node-LL2"; - } else if (((transformedLatabs & (-1 << 15)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 15)) == 0)) - && (transformedLonabs & (-1 << 15)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 15)) == 0))) { - // 15 bit value - return "node-LL3"; - } else if (((transformedLatabs & (-1 << 17)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 17)) == 0)) - && (transformedLonabs & (-1 << 17)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 17)) == 0))) { - // 17 bit value - return "node-LL4"; - } else if (((transformedLatabs & (-1 << 21)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 21)) == 0)) - && (transformedLonabs & (-1 << 21)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 21)) == 0))) { - // 21 bit value - return "node-LL5"; - } else if (((transformedLatabs & (-1 << 23)) == 0 || (transformedLat < 0 && (transformedLatabs ^ (1 << 23)) == 0)) - && (transformedLonabs & (-1 << 23)) == 0 - || (transformedLon < 0 && ((transformedLonabs ^ (1 << 23)) == 0))) { - // 23 bit value - return "node-LL6"; + } + + JsonNode sequence = JsonUtils.newNode().set(SEQUENCE_STRING, newItems); + + dataFrame.remove("items"); + + // step 2, set the content CHOICE + String replacedContentName = dataFrame.get("content").asText(); + if (replacedContentName.equals("Advisory")) { + replacedContentName = "advisory"; + } + + // The following field is called "content" but this results in a + // failed conversion to XML + // see @us.dot.its.jpo.ode.traveler.TimController.publish + dataFrame.set(TCONTENT_STRING, JsonUtils.newNode().set(replacedContentName, sequence)); + dataFrame.remove("content"); + } + + public static JsonNode buildItem(String itemStr) { + JsonNode item = null; + // check to see if it is a itis code or text + try { + item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(ITIS, Integer.valueOf(itemStr))); + // it's a number, so create "itis" code + } catch (NumberFormatException e) { + // it's a number, so create "text" + if (itemStr.startsWith("'")) { + item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(TEXT, itemStr.substring(1))); } else { - throw new IllegalArgumentException("Invalid node lat/long offset: " + transformedLat + "/" + transformedLon - + ". Values must be between a range of -0.8388608/+0.8388607 degrees."); - } - - } - - public static void replaceGeometry(ObjectNode geometry) { - - // direction HeadingSlice - // extent Extent OPTIONAL - // laneWidth LaneWidth OPTIONAL - // circle Circle - - // direction does not need to be replaced - - // extent does not need to be replaced (optional) - - // replace lane width - JsonNode laneWidth = geometry.get(LANE_WIDTH); - if (laneWidth != null) { - geometry.put(LANE_WIDTH, LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(laneWidth))); + item = JsonUtils.newNode().set(ITEM, JsonUtils.newNode().put(TEXT, itemStr)); } - - // replace circle - replaceCircle(geometry.get(CIRCLE)); - } - - public static void replaceOldRegion(ObjectNode oldRegion) { - - // old region == ValidRegion - // elements: - // direction - no changes - - // extent - no changes - JsonNode extentNode = oldRegion.get(EXTENT); - String extent = CommonUtils.enumToString(Extent.ExtentEnum.class, extentNode.asText()); - oldRegion.set(EXTENT, JsonUtils.newNode().put(extent, EMPTY_FIELD_FLAG)); - - // area - needs changes - replaceArea(oldRegion.get("area")); - } - - public static void replaceArea(JsonNode area) { - - // area contains one of: - // shapePointSet - // circle - // regionPointSet - - ObjectNode updatedNode = (ObjectNode) area; - - if (updatedNode.has(SHAPE_POINT_SET)) { - JsonNode shapePointSet = updatedNode.get(SHAPE_POINT_SET); - replaceShapePointSet(shapePointSet); - updatedNode.set(SHAPE_POINT_SET, shapePointSet); - } else if (updatedNode.has(CIRCLE)) { - replaceCircle(updatedNode.get(CIRCLE)); - } else if (updatedNode.has(REGION_POINT_SET)) { - replaceRegionPointSet(updatedNode.get(REGION_POINT_SET)); - } - } - - private static void replaceRegionPointSet(JsonNode regionPointSet) { - // regionPointSet contains: - // anchor - // zoom - // nodeList (regionList) - ObjectNode updatedNode = (ObjectNode) regionPointSet; - - // replace anchor (optional) - if (updatedNode.get(ANCHOR_POSITION) != null) { - JsonUtils.addNode(updatedNode, ANCHOR, - Position3DBuilder.dsrcPosition3D(Position3DBuilder.odePosition3D(updatedNode.get(ANCHOR_POSITION)))); - updatedNode.remove(ANCHOR_POSITION); + } + + return item; + } + + public static void replaceMsgId(ObjectNode dataFrame) { + + // + // + // + // 416784730 + // -1087827750 + // 9171 + // + // 0101010101010100 + // + // + // + // 0000 + // + // + + JsonNode msgId = dataFrame.get("msgId"); + if (msgId != null) { + ObjectNode roadSignID = (ObjectNode) msgId.get("roadSignID"); + if (roadSignID != null) { + + DsrcPosition3D position = Position3DBuilder + .dsrcPosition3D(Position3DBuilder.odePosition3D(roadSignID.get(POSITION))); + + roadSignID.putPOJO(POSITION, position); + + // mutcdCode is optional + JsonNode mutcdNode = roadSignID.get("mutcdCode"); + if (mutcdNode != null) { + roadSignID.set("mutcdCode", + JsonUtils.newNode().put(mutcdNode.asText(), EMPTY_FIELD_FLAG)); + } } + } + } - // zoom doesn't need replacement (also optional) - - // regionList is good as is and does not need replacement (required) - } - - public static void replaceCircle(JsonNode circle) { + public static ObjectNode transformRegions(JsonNode regions) throws JsonUtilsException { + ArrayNode replacedRegions = JsonUtils.newNode().arrayNode(); - // Circle ::= SEQUENCE - // center Position3D, - // radius Radius-B12, - // units DistanceUnits - // + if (regions.isArray()) { + Iterator regionsIter = regions.elements(); - ObjectNode updatedNode = (ObjectNode) circle; - - JsonNode centerPosition = null; - if (updatedNode.has(POSITION)) { - centerPosition = updatedNode.get(POSITION); - updatedNode.remove(POSITION); - } else { - centerPosition = updatedNode.get(CENTER); + while (regionsIter.hasNext()) { + JsonNode curRegion = regionsIter.next(); + replaceRegion((ObjectNode) curRegion); + replacedRegions.add(curRegion); } - - // replace center - JsonUtils.addNode(updatedNode, CENTER, - Position3DBuilder.dsrcPosition3D(Position3DBuilder.odePosition3D(centerPosition))); - - // radius does not need replacement - - // replace units - if (updatedNode.has(UNITS)) { - JsonNode units = updatedNode.get(UNITS); - String enumString = CommonUtils.enumToString(DistanceUnitsEnum.class, units.asText()); - if (enumString != null) { - updatedNode.set(UNITS, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); - } + } + + return JsonUtils.newObjectNode(GEOGRAPHICAL_PATH_STRING, replacedRegions); + } + + public static void replaceRegion(ObjectNode region) throws JsonUtilsException { + + //// EXPECTED INPUT: + // "name": "Testing TIM", + // "regulatorID": "0", + // "segmentID": "33", + // "anchorPosition": + // "latitude": "41.2500807", + // "longitude": "-111.0093847", + // "elevation": "2020.6969900289998" + // , + // "laneWidth": "7", + // "directionality": "3", + // "closedPath": "false", + // "description": "path", + // "path": {}, + // "direction": "0000000000001010" + // + + //// EXPECTED OUTPUT: + // + // .Testing TIM + // . + // ..0 + // ..33 + // . + // . + // ..412500807 + // ..-1110093847 + // ..20206 + // . + // .700 + // . + // .. + // . + // . + // .. + // . + // .0000000000010100 + // . + // . + // + + // name does not need to be replaced + + // id optional, consists of segmentID (required) + // and regulatorID (optional) + JsonNode segmentID = region.get(SEGMENT_ID); + if (segmentID != null) { + ObjectNode id = JsonUtils.newNode().put(ID, segmentID.asInt()); + JsonNode regulatorID = region.get(REGULATOR_ID); + if (regulatorID != null) { + id.put(REGION, regulatorID.asInt()); } - } - - public static void replaceShapePointSet(JsonNode shapePointSet) { - // shape point set contains: - // anchor - // lane width - // directionality - // node list - - ObjectNode updatedNode = (ObjectNode) shapePointSet; - - // replace anchor - if (updatedNode.has(ANCHOR)) { - JsonUtils.addNode(updatedNode, ANCHOR, - Position3DBuilder.dsrcPosition3D(Position3DBuilder.odePosition3D(updatedNode.get(ANCHOR)))); + region.set(ID, id); + } + // replace regulatorID and segmentID with id + ObjectNode id = JsonUtils.newNode().put(REGION, region.get(REGULATOR_ID).asInt()).put(ID, + region.get(SEGMENT_ID).asInt()); + + region.set(ID, id); + region.remove(REGULATOR_ID); + region.remove(SEGMENT_ID); + + // anchorPosition --> anchor (optional) + JsonNode anchorPos = region.get(ANCHOR_POSITION); + if (anchorPos != null) { + region.set(ANCHOR, JsonUtils.toObjectNode(Position3DBuilder + .dsrcPosition3D(Position3DBuilder.odePosition3D(region.get(ANCHOR_POSITION))).toJson())); + region.remove(ANCHOR_POSITION); + } + + // lane width (optional) + JsonNode laneWidth = region.get(LANE_WIDTH); + if (laneWidth != null) { + region.put(LANE_WIDTH, LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(laneWidth))); + } + + // directionality (optional) + if (region.has(DIRECTIONALITY)) { + JsonNode directionality = region.get(DIRECTIONALITY); + String enumString = + CommonUtils.enumToString(DirectionOfUseEnum.class, directionality.asText()); + if (enumString != null) { + region.set(DIRECTIONALITY, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); } - - // replace lane width - if (updatedNode.has(LANE_WIDTH)) { - updatedNode.put(LANE_WIDTH, LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(updatedNode.get(LANE_WIDTH)))); + } + + // closed path (optional) + JsonNode closedPath = region.get(CLOSED_PATH); + if (closedPath != null) { + region.put(CLOSED_PATH, + (closedPath.asBoolean() ? BOOLEAN_OBJECT_TRUE : BOOLEAN_OBJECT_FALSE)); + } + + // description (optional) + JsonNode descriptionNode = region.get(DESCRIPTION); + if (descriptionNode != null) { + String descriptionType = descriptionNode.asText(); + if (PATH.equals(descriptionType)) { + ObjectNode pathNode = (ObjectNode) region.get(PATH); + replacePath(pathNode); + region.set(DESCRIPTION, JsonUtils.newNode().set(PATH, pathNode)); + } else if (GEOMETRY.equals(descriptionType)) { + ObjectNode newGeometry = (ObjectNode) region.get(GEOMETRY); + replaceGeometry(newGeometry); + region.set(DESCRIPTION, JsonUtils.newNode().set(GEOMETRY, newGeometry)); + } else if (OLD_REGION.equals(descriptionType)) { + ObjectNode newOldRegion = (ObjectNode) region.get(OLD_REGION); + replaceOldRegion(newOldRegion); + region.set(DESCRIPTION, JsonUtils.newNode().set(OLD_REGION, newOldRegion)); } - - // replace directionality - if (updatedNode.has(DIRECTIONALITY)) { - JsonNode directionality = updatedNode.get(DIRECTIONALITY); - String enumString = CommonUtils.enumToString(DirectionOfUseEnum.class, directionality.asText()); - if (enumString != null) { - updatedNode.set(DIRECTIONALITY, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); - } + region.remove(descriptionType); + } + } + + private static void replacePath(ObjectNode pathNode) { + + //// EXPECTED INPUT: + // "path": + // "scale": "0", + // "type": "ll", + // "nodes": [] + // + + //// EXPECTED OUTPUT: + // + // .0 + // . + // .. + // ... + // ... + // .. + // . + // + + // zoom does not need to be replaced + String nodeType = pathNode.get(TYPE).asText(); + JsonNode nodes = pathNode.get(NODES); + JsonNode nodeList; + if (LL.equals(nodeType)) { + nodeList = JsonUtils.newNode().set("NodeLL", transformNodeSetLL(nodes)); + pathNode.set(OFFSET, JsonUtils.newNode().set(LL, JsonUtils.newNode().set(NODES, nodeList))); + } else if (XY.equals(nodeType)) { + nodeList = JsonUtils.newNode().set(NODE_XY2, transformNodeSetXY(nodes)); + pathNode.set(OFFSET, JsonUtils.newNode().set(XY, JsonUtils.newNode().set(NODES, nodeList))); + } + pathNode.remove(NODES); + pathNode.remove(TYPE); + + } + + private static ArrayNode transformNodeSetLL(JsonNode nodes) { + + //// EXPECTED INPUT: + // "nodes": [] + + // EXPECTED OUTPUT: + // + // . + // . + // . + // . + // + + ArrayNode outputNodeList = JsonUtils.newNode().arrayNode(); + + if (nodes.isArray()) { + Iterator nodeListIter = nodes.elements(); + + while (nodeListIter.hasNext()) { + JsonNode inputNode = nodeListIter.next(); + outputNodeList.add(transformNodeLL(inputNode)); } - - // replace node list - if (updatedNode.has(NODE_LIST)) { - ObjectNode nodeList = (ObjectNode) updatedNode.get(NODE_LIST); - if (nodeList.has(NODES)) { - ArrayNode nodes = transformNodeSetXY(nodeList.get(NODES)); - nodeList.set(NODES, nodes); - } else if (nodeList.has(COMPUTED)) { - JsonNode computedLane = nodeList.get(COMPUTED); - replaceComputedLane(computedLane); - } + } + + return outputNodeList; + } + + private static ObjectNode transformNodeLL(JsonNode oldNode) { + + //// EXPECTED INPUT: + // + // "nodeLong": "0.0031024", + // "nodeLat": "0.0014506", + // "delta": "node-LL3" + // + + //// EXPECTED OUTPUT: + // + // . + // .. + // ...14506 + // ...31024 + // .. + // . + // + + BigDecimal latOffset = JsonUtils.decimalValue(oldNode.get(NODE_LAT)); + BigDecimal longOffset = JsonUtils.decimalValue(oldNode.get(NODE_LONG)); + JsonNode delta = oldNode.get(DELTA); + Long transformedLat = null; + Long transformedLong = null; + + ObjectNode innerNode = JsonUtils.newNode(); + ObjectNode deltaNode = (ObjectNode) JsonUtils.newNode().set(DELTA, innerNode); + ObjectNode latLong = JsonUtils.newNode(); + String deltaText = delta.asText(); + if (deltaText.startsWith("node-LL")) { + transformedLat = OffsetLLBuilder.offsetLL(latOffset); + transformedLong = OffsetLLBuilder.offsetLL(longOffset); + if (deltaText.equals("node-LL")) { + deltaText = nodeOffsetPointLL(transformedLat, transformedLong); } - } - - public static void replaceComputedLane(JsonNode jsonNode) { - ObjectNode updatedNode = (ObjectNode) jsonNode; - - // Nothing to do for referenceLaneId LaneID - - // offsetXaxis CHOICE - // small DrivenLineOffsetSm, - // large DrivenLineOffsetLg - // - replaceScale(updatedNode, OFFSET_X_AXIS); - - // offsetYaxis CHOICE - // small DrivenLineOffsetSm, - // large DrivenLineOffsetLg - // - replaceScale(updatedNode, OFFSET_Y_AXIS); - - // rotateXY Angle OPTIONAL - if (updatedNode.has(ROTATE_XY)) { - updatedNode.put(ROTATE_XY, AngleBuilder.angle(JsonUtils.decimalValue(updatedNode.get(ROTATE_XY)))); + } else if (NODE_LAT_LON.equals(deltaText)) { + transformedLat = LatitudeBuilder.j2735Latitude(latOffset); + transformedLong = LongitudeBuilder.j2735Longitude(longOffset); + } + + innerNode.set(deltaText, latLong); + latLong.put(LAT, transformedLat).put(LON, transformedLong); + + return deltaNode; + } + + // -- Nodes with LL content Span at the equator when using a zoom of one: + // node-LL1 Node-LL-24B, -- within +- 22.634554 meters of last node + // node-LL2 Node-LL-28B, -- within +- 90.571389 meters of last node + // node-LL3 Node-LL-32B, -- within +- 362.31873 meters of last node + // node-LL4 Node-LL-36B, -- within +- 01.449308 Kmeters of last node + // node-LL5 Node-LL-44B, -- within +- 23.189096 Kmeters of last node + // node-LL6 Node-LL-48B, -- within +- 92.756481 Kmeters of last node + // node-LatLon Node-LLmD-64b, -- node is a full 32b Lat/Lon range + private static String nodeOffsetPointLL(long transformedLat, long transformedLon) { + long transformedLatabs = Math.abs(transformedLat); + long transformedLonabs = Math.abs(transformedLon); + if (((transformedLatabs & (-1 << 11)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 11)) == 0)) + && (transformedLonabs & (-1 << 11)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 11)) == 0))) { + // 11 bit value + return "node-LL1"; + } else if (((transformedLatabs & (-1 << 13)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 13)) == 0)) + && (transformedLonabs & (-1 << 13)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 13)) == 0))) { + // 13 bit value + return "node-LL2"; + } else if (((transformedLatabs & (-1 << 15)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 15)) == 0)) + && (transformedLonabs & (-1 << 15)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 15)) == 0))) { + // 15 bit value + return "node-LL3"; + } else if (((transformedLatabs & (-1 << 17)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 17)) == 0)) + && (transformedLonabs & (-1 << 17)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 17)) == 0))) { + // 17 bit value + return "node-LL4"; + } else if (((transformedLatabs & (-1 << 21)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 21)) == 0)) + && (transformedLonabs & (-1 << 21)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 21)) == 0))) { + // 21 bit value + return "node-LL5"; + } else if (((transformedLatabs & (-1 << 23)) == 0 || + (transformedLat < 0 && (transformedLatabs ^ (1 << 23)) == 0)) + && (transformedLonabs & (-1 << 23)) == 0 + || (transformedLon < 0 && ((transformedLonabs ^ (1 << 23)) == 0))) { + // 23 bit value + return "node-LL6"; + } else { + throw new IllegalArgumentException( + "Invalid node lat/long offset: " + transformedLat + "/" + transformedLon + + ". Values must be between a range of -0.8388608/+0.8388607 degrees."); + } + + } + + public static void replaceGeometry(ObjectNode geometry) { + + // direction HeadingSlice + // extent Extent OPTIONAL + // laneWidth LaneWidth OPTIONAL + // circle Circle + + // direction does not need to be replaced + + // extent does not need to be replaced (optional) + + // replace lane width + JsonNode laneWidth = geometry.get(LANE_WIDTH); + if (laneWidth != null) { + geometry.put(LANE_WIDTH, LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(laneWidth))); + } + + // replace circle + replaceCircle(geometry.get(CIRCLE)); + } + + public static void replaceOldRegion(ObjectNode oldRegion) { + + // old region == ValidRegion + // elements: + // direction - no changes + + // extent - no changes + JsonNode extentNode = oldRegion.get(EXTENT); + String extent = CommonUtils.enumToString(Extent.ExtentEnum.class, extentNode.asText()); + oldRegion.set(EXTENT, JsonUtils.newNode().put(extent, EMPTY_FIELD_FLAG)); + + // area - needs changes + replaceArea(oldRegion.get("area")); + } + + public static void replaceArea(JsonNode area) { + + // area contains one of: + // shapePointSet + // circle + // regionPointSet + + ObjectNode updatedNode = (ObjectNode) area; + + if (updatedNode.has(SHAPE_POINT_SET)) { + JsonNode shapePointSet = updatedNode.get(SHAPE_POINT_SET); + replaceShapePointSet(shapePointSet); + updatedNode.set(SHAPE_POINT_SET, shapePointSet); + } else if (updatedNode.has(CIRCLE)) { + replaceCircle(updatedNode.get(CIRCLE)); + } else if (updatedNode.has(REGION_POINT_SET)) { + replaceRegionPointSet(updatedNode.get(REGION_POINT_SET)); + } + } + + private static void replaceRegionPointSet(JsonNode regionPointSet) { + // regionPointSet contains: + // anchor + // zoom + // nodeList (regionList) + ObjectNode updatedNode = (ObjectNode) regionPointSet; + + // replace anchor (optional) + if (updatedNode.get(ANCHOR_POSITION) != null) { + JsonUtils.addNode(updatedNode, ANCHOR, + Position3DBuilder.dsrcPosition3D( + Position3DBuilder.odePosition3D(updatedNode.get(ANCHOR_POSITION)))); + updatedNode.remove(ANCHOR_POSITION); + } + + // zoom doesn't need replacement (also optional) + + // regionList is good as is and does not need replacement (required) + } + + public static void replaceCircle(JsonNode circle) { + + // Circle ::= SEQUENCE + // center Position3D, + // radius Radius-B12, + // units DistanceUnits + // + + ObjectNode updatedNode = (ObjectNode) circle; + + JsonNode centerPosition = null; + if (updatedNode.has(POSITION)) { + centerPosition = updatedNode.get(POSITION); + updatedNode.remove(POSITION); + } else { + centerPosition = updatedNode.get(CENTER); + } + + // replace center + JsonUtils.addNode(updatedNode, CENTER, + Position3DBuilder.dsrcPosition3D(Position3DBuilder.odePosition3D(centerPosition))); + + // radius does not need replacement + + // replace units + if (updatedNode.has(UNITS)) { + JsonNode units = updatedNode.get(UNITS); + String enumString = CommonUtils.enumToString(DistanceUnitsEnum.class, units.asText()); + if (enumString != null) { + updatedNode.set(UNITS, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); } - - // scaleXaxis Scale-B12 OPTIONAL - if (updatedNode.has(SCALE_X_AXIS)) { - updatedNode.put(SCALE_X_AXIS, ScaleB12Builder.scaleB12(JsonUtils.decimalValue(updatedNode.get(SCALE_X_AXIS)))); + } + } + + public static void replaceShapePointSet(JsonNode shapePointSet) { + // shape point set contains: + // anchor + // lane width + // directionality + // node list + + ObjectNode updatedNode = (ObjectNode) shapePointSet; + + // replace anchor + if (updatedNode.has(ANCHOR)) { + JsonUtils.addNode(updatedNode, ANCHOR, + Position3DBuilder.dsrcPosition3D( + Position3DBuilder.odePosition3D(updatedNode.get(ANCHOR)))); + } + + // replace lane width + if (updatedNode.has(LANE_WIDTH)) { + updatedNode.put(LANE_WIDTH, + LaneWidthBuilder.laneWidth(JsonUtils.decimalValue(updatedNode.get(LANE_WIDTH)))); + } + + // replace directionality + if (updatedNode.has(DIRECTIONALITY)) { + JsonNode directionality = updatedNode.get(DIRECTIONALITY); + String enumString = + CommonUtils.enumToString(DirectionOfUseEnum.class, directionality.asText()); + if (enumString != null) { + updatedNode.set(DIRECTIONALITY, JsonUtils.newNode().put(enumString, EMPTY_FIELD_FLAG)); } - - // scaleYaxis Scale-B12 OPTIONAL - if (updatedNode.has(SCALE_Y_AXIS)) { - updatedNode.put(SCALE_Y_AXIS, ScaleB12Builder.scaleB12(JsonUtils.decimalValue(updatedNode.get(SCALE_Y_AXIS)))); + } + + // replace node list + if (updatedNode.has(NODE_LIST)) { + ObjectNode nodeList = (ObjectNode) updatedNode.get(NODE_LIST); + if (nodeList.has(NODES)) { + ArrayNode nodes = transformNodeSetXY(nodeList.get(NODES)); + nodeList.set(NODES, nodes); + } else if (nodeList.has(COMPUTED)) { + JsonNode computedLane = nodeList.get(COMPUTED); + replaceComputedLane(computedLane); } - } - - public static void replaceScale(ObjectNode updatedNode, String scale) { - if (updatedNode.has(scale)) { - int scaleX = updatedNode.get(scale).asInt(); - String key = "large"; - if (-2048 <= scaleX && scaleX <= 2047) { - key = "small"; - } - - ObjectNode node = JsonUtils.newObjectNode(key, scaleX); - updatedNode.set(scale, node); + } + } + + public static void replaceComputedLane(JsonNode jsonNode) { + ObjectNode updatedNode = (ObjectNode) jsonNode; + + // Nothing to do for referenceLaneId LaneID + + // offsetXaxis CHOICE + // small DrivenLineOffsetSm, + // large DrivenLineOffsetLg + // + replaceScale(updatedNode, OFFSET_X_AXIS); + + // offsetYaxis CHOICE + // small DrivenLineOffsetSm, + // large DrivenLineOffsetLg + // + replaceScale(updatedNode, OFFSET_Y_AXIS); + + // rotateXY Angle OPTIONAL + if (updatedNode.has(ROTATE_XY)) { + updatedNode.put(ROTATE_XY, + AngleBuilder.angle(JsonUtils.decimalValue(updatedNode.get(ROTATE_XY)))); + } + + // scaleXaxis Scale-B12 OPTIONAL + if (updatedNode.has(SCALE_X_AXIS)) { + updatedNode.put(SCALE_X_AXIS, + ScaleB12Builder.scaleB12(JsonUtils.decimalValue(updatedNode.get(SCALE_X_AXIS)))); + } + + // scaleYaxis Scale-B12 OPTIONAL + if (updatedNode.has(SCALE_Y_AXIS)) { + updatedNode.put(SCALE_Y_AXIS, + ScaleB12Builder.scaleB12(JsonUtils.decimalValue(updatedNode.get(SCALE_Y_AXIS)))); + } + } + + public static void replaceScale(ObjectNode updatedNode, String scale) { + if (updatedNode.has(scale)) { + int scaleX = updatedNode.get(scale).asInt(); + String key = "large"; + if (-2048 <= scaleX && scaleX <= 2047) { + key = "small"; } - } - - public static ArrayNode transformNodeSetXY(JsonNode inputNodeList) { - - //// EXPECTED INPUT: - // "nodes": [] - - // EXPECTED OUTPUT: - // - // . - // . - // . - // . - // - ArrayNode outputNodeList = JsonUtils.newNode().arrayNode(); + ObjectNode node = JsonUtils.newObjectNode(key, scaleX); + updatedNode.set(scale, node); + } + } - if (inputNodeList.isArray()) { - Iterator nodeListIter = inputNodeList.elements(); + public static ArrayNode transformNodeSetXY(JsonNode inputNodeList) { - while (nodeListIter.hasNext()) { - JsonNode inputNode = nodeListIter.next(); - outputNodeList.add(transformNodeXY(inputNode)); - } - } - - return outputNodeList; - } + //// EXPECTED INPUT: + // "nodes": [] - public static JsonNode transformNodeXY(JsonNode oldNode) { + // EXPECTED OUTPUT: + // + // . + // . + // . + // . + // - // nodexy contains: - // delta NodeOffsetPointXY - // attributes NodeAttributeSetXY (optional) + ArrayNode outputNodeList = JsonUtils.newNode().arrayNode(); - ObjectNode nodexy = transformNodeOffsetPointXY(oldNode); + if (inputNodeList.isArray()) { + Iterator nodeListIter = inputNodeList.elements(); - if (oldNode.has(ATTRIBUTES)) { - nodexy.set(ATTRIBUTES, transformNodeAttributeSetXY(oldNode.get(ATTRIBUTES))); + while (nodeListIter.hasNext()) { + JsonNode inputNode = nodeListIter.next(); + outputNodeList.add(transformNodeXY(inputNode)); } + } - return nodexy; - } + return outputNodeList; + } - private static ObjectNode transformNodeAttributeSetXY(JsonNode jsonNode) { - // localNode NodeAttributeXYList OPTIONAL, - // disabled SegmentAttributeXYList OPTIONAL, - // enabled SegmentAttributeXYList OPTIONAL, - // data LaneDataAttributeList OPTIONAL, - // dWidth Offset-B10 OPTIONAL, - // dElevation Offset-B10 OPTIONAL, + public static JsonNode transformNodeXY(JsonNode oldNode) { - ObjectNode updatedNode = JsonUtils.newNode(); + // nodexy contains: + // delta NodeOffsetPointXY + // attributes NodeAttributeSetXY (optional) - // localNode NodeAttributeXYList does not need to be replaced + ObjectNode nodexy = transformNodeOffsetPointXY(oldNode); - // disabled SegmentAttributeXYList does not need to be replaced - // enabled SegmentAttributeXYList does not need to be replaced + if (oldNode.has(ATTRIBUTES)) { + nodexy.set(ATTRIBUTES, transformNodeAttributeSetXY(oldNode.get(ATTRIBUTES))); + } - if (jsonNode.has(DATA)) { - updatedNode.set(DATA, transformLaneDataAttributeList(jsonNode.get(DATA))); - } - if (jsonNode.has(D_WIDTH)) { - updatedNode.put(D_WIDTH, OffsetXyBuilder.offsetXy(JsonUtils.decimalValue(jsonNode.get(D_WIDTH)))); - } + return nodexy; + } - if (jsonNode.has(D_ELEVATION)) { - updatedNode.put(D_ELEVATION, OffsetXyBuilder.offsetXy(JsonUtils.decimalValue(jsonNode.get(D_ELEVATION)))); - } - return updatedNode; - } + private static ObjectNode transformNodeAttributeSetXY(JsonNode jsonNode) { + // localNode NodeAttributeXYList OPTIONAL, + // disabled SegmentAttributeXYList OPTIONAL, + // enabled SegmentAttributeXYList OPTIONAL, + // data LaneDataAttributeList OPTIONAL, + // dWidth Offset-B10 OPTIONAL, + // dElevation Offset-B10 OPTIONAL, - private static ArrayNode transformLaneDataAttributeList(JsonNode laneDataAttribute) { + ObjectNode updatedNode = JsonUtils.newNode(); - ArrayNode updatedLaneDataAttributeList = JsonUtils.newNode().arrayNode(); + // localNode NodeAttributeXYList does not need to be replaced - if (laneDataAttribute.isArray()) { - Iterator laneDataAttributeListIter = laneDataAttribute.elements(); + // disabled SegmentAttributeXYList does not need to be replaced + // enabled SegmentAttributeXYList does not need to be replaced - while (laneDataAttributeListIter.hasNext()) { - JsonNode oldNode = laneDataAttributeListIter.next(); - replaceLaneDataAttribute(oldNode); - updatedLaneDataAttributeList.add(oldNode); - } - } - return updatedLaneDataAttributeList; - } - - public static void replaceLaneDataAttribute(JsonNode oldNode) { - // choice between 1 of the following: - // pathEndPointAngle DeltaAngle - // laneCrownPointCenter RoadwayCrownAngle - // laneCrownPointLeft RoadwayCrownAngle - // laneCrownPointRight RoadwayCrownAngle - // laneAngle MergeDivergeNodeAngle - // speedLimits SpeedLimitList - - ObjectNode updatedNode = (ObjectNode) oldNode; - - // pathEndPointAngle DeltaAngle does not need to be replaced - if (oldNode.has("pathEndPointAngle")) { - // do nothing - } else if (oldNode.has(LANE_CROWN_POINT_CENTER)) { - updatedNode.put(LANE_CROWN_POINT_CENTER, RoadwayCrownAngleBuilder - .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_CENTER)))); - } else if (oldNode.has(LANE_CROWN_POINT_LEFT)) { - updatedNode.put(LANE_CROWN_POINT_LEFT, RoadwayCrownAngleBuilder - .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_LEFT)))); - } else if (oldNode.has(LANE_CROWN_POINT_RIGHT)) { - updatedNode.put(LANE_CROWN_POINT_RIGHT, RoadwayCrownAngleBuilder - .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_RIGHT)))); - } else if (oldNode.has(LANE_ANGLE)) { - updatedNode.put(LANE_ANGLE, - MergeDivergeNodeAngleBuilder.mergeDivergeNodeAngle(JsonUtils.decimalValue(updatedNode.get(LANE_ANGLE)))); - } else if (oldNode.has(SPEED_LIMITS)) { - replaceSpeedLimitList(updatedNode.get(SPEED_LIMITS)); - } - } + if (jsonNode.has(DATA)) { + updatedNode.set(DATA, transformLaneDataAttributeList(jsonNode.get(DATA))); + } + if (jsonNode.has(D_WIDTH)) { + updatedNode.put(D_WIDTH, + OffsetXyBuilder.offsetXy(JsonUtils.decimalValue(jsonNode.get(D_WIDTH)))); + } - private static void replaceSpeedLimitList(JsonNode speedLimitList) { + if (jsonNode.has(D_ELEVATION)) { + updatedNode.put(D_ELEVATION, + OffsetXyBuilder.offsetXy(JsonUtils.decimalValue(jsonNode.get(D_ELEVATION)))); + } + return updatedNode; + } - if (speedLimitList.isArray()) { - Iterator speedLimitListIter = speedLimitList.elements(); + private static ArrayNode transformLaneDataAttributeList(JsonNode laneDataAttribute) { - while (speedLimitListIter.hasNext()) { - JsonNode oldNode = speedLimitListIter.next(); - replaceRegulatorySpeedLimit(oldNode); - } - } - } - - private static void replaceRegulatorySpeedLimit(JsonNode regulatorySpeedLimitNode) { - // contains: - // type SpeedLimitType - // speed Velocity + ArrayNode updatedLaneDataAttributeList = JsonUtils.newNode().arrayNode(); - ObjectNode updatedNode = (ObjectNode) regulatorySpeedLimitNode; + if (laneDataAttribute.isArray()) { + Iterator laneDataAttributeListIter = laneDataAttribute.elements(); - // type - JsonNode typeNode = regulatorySpeedLimitNode.get(TYPE); - String type = CommonUtils.enumToString(SpeedLimitTypeEnum.class, typeNode.asText()); - if (type != null) { - updatedNode.set(TYPE, JsonUtils.newNode().put(type, EMPTY_FIELD_FLAG)); + while (laneDataAttributeListIter.hasNext()) { + JsonNode oldNode = laneDataAttributeListIter.next(); + replaceLaneDataAttribute(oldNode); + updatedLaneDataAttributeList.add(oldNode); } - - // replace velocity - updatedNode.put(SPEED, VelocityBuilder.velocity(JsonUtils.decimalValue(updatedNode.get(SPEED)))); - - } - - public static ObjectNode transformNodeOffsetPointXY(JsonNode oldNode) { - //// EXPECTED INPUT: - // - // "nodeLong": "0.0031024", - // "nodeLat": "0.0014506", - // "delta": "node-LL3" - // - - //// EXPECTED OUTPUT: - // - // . - // .. - // ...14506 - // ...31024 - // .. - // . - // - - JsonNode delta = oldNode.get(DELTA); - - ObjectNode innerNode = JsonUtils.newNode(); - ObjectNode deltaNode = JsonUtils.newNode(); - String deltaText = delta.asText(); - if (deltaText.startsWith(NODE_XY)) { - BigDecimal xOffset = JsonUtils.decimalValue(oldNode.get(X)); - BigDecimal yOffset = JsonUtils.decimalValue(oldNode.get(Y)); - Long transformedX = OffsetXyBuilder.offsetXy(xOffset); - Long transformedY = OffsetXyBuilder.offsetXy(yOffset); - ObjectNode xy = JsonUtils.newNode().put(X, transformedX).put(Y, transformedY); - if (deltaText.equals(NODE_XY)) { - innerNode.set(nodeOffsetPointXY(transformedX, transformedY), xy); - } else { - innerNode.set(deltaText, xy); - } - } else if (deltaText.startsWith(NODE_LAT_LON)) { - BigDecimal lonOffset = JsonUtils.decimalValue(oldNode.get(NODE_LONG)); - BigDecimal latOffset = JsonUtils.decimalValue(oldNode.get(NODE_LAT)); - Long transformedLon = LatitudeBuilder.j2735Latitude(lonOffset); - Long transformedLat = LongitudeBuilder.j2735Longitude(latOffset); - ObjectNode latLong = JsonUtils.newNode().put(LON, transformedLon).put(LAT, transformedLat); - if (deltaText.equals(NODE_XY)) { - innerNode.set(nodeOffsetPointLL(transformedLat, transformedLon), latLong); - } else { - innerNode.set(deltaText, latLong); - } + } + return updatedLaneDataAttributeList; + } + + public static void replaceLaneDataAttribute(JsonNode oldNode) { + // choice between 1 of the following: + // pathEndPointAngle DeltaAngle + // laneCrownPointCenter RoadwayCrownAngle + // laneCrownPointLeft RoadwayCrownAngle + // laneCrownPointRight RoadwayCrownAngle + // laneAngle MergeDivergeNodeAngle + // speedLimits SpeedLimitList + + ObjectNode updatedNode = (ObjectNode) oldNode; + + // pathEndPointAngle DeltaAngle does not need to be replaced + if (oldNode.has("pathEndPointAngle")) { + // do nothing + } else if (oldNode.has(LANE_CROWN_POINT_CENTER)) { + updatedNode.put(LANE_CROWN_POINT_CENTER, RoadwayCrownAngleBuilder + .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_CENTER)))); + } else if (oldNode.has(LANE_CROWN_POINT_LEFT)) { + updatedNode.put(LANE_CROWN_POINT_LEFT, RoadwayCrownAngleBuilder + .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_LEFT)))); + } else if (oldNode.has(LANE_CROWN_POINT_RIGHT)) { + updatedNode.put(LANE_CROWN_POINT_RIGHT, RoadwayCrownAngleBuilder + .roadwayCrownAngle(JsonUtils.decimalValue(updatedNode.get(LANE_CROWN_POINT_RIGHT)))); + } else if (oldNode.has(LANE_ANGLE)) { + updatedNode.put(LANE_ANGLE, + MergeDivergeNodeAngleBuilder.mergeDivergeNodeAngle( + JsonUtils.decimalValue(updatedNode.get(LANE_ANGLE)))); + } else if (oldNode.has(SPEED_LIMITS)) { + replaceSpeedLimitList(updatedNode.get(SPEED_LIMITS)); + } + } + + private static void replaceSpeedLimitList(JsonNode speedLimitList) { + + if (speedLimitList.isArray()) { + Iterator speedLimitListIter = speedLimitList.elements(); + + while (speedLimitListIter.hasNext()) { + JsonNode oldNode = speedLimitListIter.next(); + replaceRegulatorySpeedLimit(oldNode); } - - deltaNode.set(DELTA, innerNode); - - return deltaNode; - - } - - // NodeOffsetPointXY contains one of: - // node-XY1 Node-XY-20b, -- node is within 5.11m of last node - // node-XY2 Node-XY-22b, -- node is within 10.23m of last node - // node-XY3 Node-XY-24b, -- node is within 20.47m of last node - // node-XY4 Node-XY-26b, -- node is within 40.96m of last node - // node-XY5 Node-XY-28b, -- node is within 81.91m of last node - // node-XY6 Node-XY-32b, -- node is within 327.67m of last node - // node-LatLon Node-LLmD-64b, -- node is a full 32b Lat/Lon range - private static String nodeOffsetPointXY(long transformedX, long transformedY) { - long transformed = Math.abs(transformedX) | Math.abs(transformedY); - if ((transformed & (-1 << 10)) == 0) { - return "node-XY1"; - } else if ((transformed & (-1 << 11)) == 0) { - return "node-XY2"; - } else if ((transformed & (-1 << 12)) == 0) { - return "node-XY3"; - } else if ((transformed & (-1 << 13)) == 0) { - return "node-XY4"; - } else if ((transformed & (-1 << 14)) == 0) { - return "node-XY5"; - } else if ((transformed & (-1 << 16)) == 0) { - return "node-XY6"; + } + } + + private static void replaceRegulatorySpeedLimit(JsonNode regulatorySpeedLimitNode) { + // contains: + // type SpeedLimitType + // speed Velocity + + ObjectNode updatedNode = (ObjectNode) regulatorySpeedLimitNode; + + // type + JsonNode typeNode = regulatorySpeedLimitNode.get(TYPE); + String type = CommonUtils.enumToString(SpeedLimitTypeEnum.class, typeNode.asText()); + if (type != null) { + updatedNode.set(TYPE, JsonUtils.newNode().put(type, EMPTY_FIELD_FLAG)); + } + + // replace velocity + updatedNode.put(SPEED, + VelocityBuilder.velocity(JsonUtils.decimalValue(updatedNode.get(SPEED)))); + + } + + public static ObjectNode transformNodeOffsetPointXY(JsonNode oldNode) { + //// EXPECTED INPUT: + // + // "nodeLong": "0.0031024", + // "nodeLat": "0.0014506", + // "delta": "node-LL3" + // + + //// EXPECTED OUTPUT: + // + // . + // .. + // ...14506 + // ...31024 + // .. + // . + // + + JsonNode delta = oldNode.get(DELTA); + + ObjectNode innerNode = JsonUtils.newNode(); + ObjectNode deltaNode = JsonUtils.newNode(); + String deltaText = delta.asText(); + if (deltaText.startsWith(NODE_XY)) { + BigDecimal xOffset = JsonUtils.decimalValue(oldNode.get(X)); + BigDecimal yOffset = JsonUtils.decimalValue(oldNode.get(Y)); + Long transformedX = OffsetXyBuilder.offsetXy(xOffset); + Long transformedY = OffsetXyBuilder.offsetXy(yOffset); + ObjectNode xy = JsonUtils.newNode().put(X, transformedX).put(Y, transformedY); + if (deltaText.equals(NODE_XY)) { + innerNode.set(nodeOffsetPointXY(transformedX, transformedY), xy); } else { - throw new IllegalArgumentException("Invalid node X/Y offset: " + transformedX + "/" + transformedY - + ". Values must be between a range of -327.68/+327.67 meters."); + innerNode.set(deltaText, xy); } - } - - /** - * Ensures compliance with the J2735 2024 standard by checking for old fields in the given data frame. - * - * @param dataFrame the JSON object representing the data frame to be checked - * @throws IllegalArgumentException if any old fields are found - */ - public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { - // Check and throw exception if old fields are found - if (dataFrame.has(SSP_MSG_CONTENT) || dataFrame.has(SSP_MSG_TYPES) || - dataFrame.has(SSP_TIM_RIGHTS) || dataFrame.has(SSP_LOCATION_RIGHTS) || - dataFrame.has(SSP_MSG_RIGHTS_1) || dataFrame.has(SSP_MSG_RIGHTS_2) || - dataFrame.has(NOT_USED) || dataFrame.has(NOT_USED_1) || - dataFrame.has(NOT_USED_2) || dataFrame.has(NOT_USED_3) || - dataFrame.has(DURATON_TIME_MISSPELLED)) { - throw new IllegalArgumentException("Data frame contains old fields that are not compliant with J2735 2024. Deserialization should prevent this."); + } else if (deltaText.startsWith(NODE_LAT_LON)) { + BigDecimal lonOffset = JsonUtils.decimalValue(oldNode.get(NODE_LONG)); + BigDecimal latOffset = JsonUtils.decimalValue(oldNode.get(NODE_LAT)); + Long transformedLon = LatitudeBuilder.j2735Latitude(lonOffset); + Long transformedLat = LongitudeBuilder.j2735Longitude(latOffset); + ObjectNode latLong = JsonUtils.newNode().put(LON, transformedLon).put(LAT, transformedLat); + if (deltaText.equals(NODE_XY)) { + innerNode.set(nodeOffsetPointLL(transformedLat, transformedLon), latLong); + } else { + innerNode.set(deltaText, latLong); } - } + } + + deltaNode.set(DELTA, innerNode); + + return deltaNode; + + } + + // NodeOffsetPointXY contains one of: + // node-XY1 Node-XY-20b, -- node is within 5.11m of last node + // node-XY2 Node-XY-22b, -- node is within 10.23m of last node + // node-XY3 Node-XY-24b, -- node is within 20.47m of last node + // node-XY4 Node-XY-26b, -- node is within 40.96m of last node + // node-XY5 Node-XY-28b, -- node is within 81.91m of last node + // node-XY6 Node-XY-32b, -- node is within 327.67m of last node + // node-LatLon Node-LLmD-64b, -- node is a full 32b Lat/Lon range + private static String nodeOffsetPointXY(long transformedX, long transformedY) { + long transformed = Math.abs(transformedX) | Math.abs(transformedY); + if ((transformed & (-1 << 10)) == 0) { + return "node-XY1"; + } else if ((transformed & (-1 << 11)) == 0) { + return "node-XY2"; + } else if ((transformed & (-1 << 12)) == 0) { + return "node-XY3"; + } else if ((transformed & (-1 << 13)) == 0) { + return "node-XY4"; + } else if ((transformed & (-1 << 14)) == 0) { + return "node-XY5"; + } else if ((transformed & (-1 << 16)) == 0) { + return "node-XY6"; + } else { + throw new IllegalArgumentException( + "Invalid node X/Y offset: " + transformedX + "/" + transformedY + + ". Values must be between a range of -327.68/+327.67 meters."); + } + } + + /** + * Ensures compliance with the J2735 2024 standard by checking for old fields in the given data frame. + * + * @param dataFrame the JSON object representing the data frame to be checked + * @throws IllegalArgumentException if any old fields are found + */ + public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { + // Check and throw exception if old fields are found + if (dataFrame.has(SSP_MSG_CONTENT) || dataFrame.has(SSP_MSG_TYPES) || + dataFrame.has(SSP_TIM_RIGHTS) || dataFrame.has(SSP_LOCATION_RIGHTS) || + dataFrame.has(SSP_MSG_RIGHTS_1) || dataFrame.has(SSP_MSG_RIGHTS_2) || + dataFrame.has(NOT_USED) || dataFrame.has(NOT_USED_1) || + dataFrame.has(NOT_USED_2) || dataFrame.has(NOT_USED_3) || + dataFrame.has(DURATON_TIME_MISSPELLED)) { + throw new IllegalArgumentException( + "Data frame contains old fields that are not compliant with J2735 2024. Deserialization should prevent this."); + } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java index 7bb4b138f..b64dfeb32 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -21,39 +22,39 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "lat", "long", "elevation" }) +@JsonPropertyOrder({"lat", "long", "elevation"}) @EqualsAndHashCode(callSuper = false) public class Anchor extends Asn1Object { - private static final long serialVersionUID = 1L; - private String lat; - private String llong; - private String elevation; - - @JsonProperty("lat") - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } - - @JsonProperty("long") - public String getLlong() { - return llong; - } - - public void setLlong(String llong) { - this.llong = llong; - } - - @JsonProperty("elevation") - public String getElevation() { - return elevation; - } - - public void setElevation(String elevation) { - this.elevation = elevation; - } + private static final long serialVersionUID = 1L; + private String lat; + private String llong; + private String elevation; + + @JsonProperty("lat") + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } + + @JsonProperty("long") + public String getLlong() { + return llong; + } + + public void setLlong(String llong) { + this.llong = llong; + } + + @JsonProperty("elevation") + public String getElevation() { + return elevation; + } + + public void setElevation(String elevation) { + this.elevation = elevation; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java index 8d3b70796..897269f7b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java @@ -6,26 +6,31 @@ @EqualsAndHashCode(callSuper = false) public class Area extends Asn1Object { private static final long serialVersionUID = 1L; - + private ShapePointSet shapepoint; private Circle circle; private RegionPointSet regionPoint; - + public ShapePointSet getShapepoint() { return shapepoint; } + public void setShapepoint(ShapePointSet shapepoint) { this.shapepoint = shapepoint; } + public Circle getCircle() { return circle; } + public void setCircle(Circle circle) { this.circle = circle; } + public RegionPointSet getRegionPoint() { return regionPoint; } + public void setRegionPoint(RegionPointSet regionPoint) { this.regionPoint = regionPoint; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java index 9690a9d53..b73ac4f7a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -21,42 +22,42 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "center", "radius", "units" }) +@JsonPropertyOrder({"center", "radius", "units"}) @EqualsAndHashCode(callSuper = false) public class Circle extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @JsonProperty("center") - private Position center; + @JsonProperty("center") + private Position center; - @JsonProperty("radius") - private String radius; + @JsonProperty("radius") + private String radius; - @JsonProperty("units") - private DistanceUnits units; + @JsonProperty("units") + private DistanceUnits units; - public Position getCenter() { - return center; - } + public Position getCenter() { + return center; + } - public void setCenter(Position center) { - this.center = center; - } + public void setCenter(Position center) { + this.center = center; + } - public String getRadius() { - return radius; - } + public String getRadius() { + return radius; + } - public void setRadius(String radius) { - this.radius = radius; - } + public void setRadius(String radius) { + this.radius = radius; + } - public DistanceUnits getUnits() { - return units; - } + public DistanceUnits getUnits() { + return units; + } - public void setUnits(DistanceUnits units) { - this.units = units; - } + public void setUnits(DistanceUnits units) { + this.units = units; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java index f4378731d..22e4e06dc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java @@ -7,52 +7,64 @@ public class ComputedLane extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - + private int referenceLaneId; private OffsetAxis offsetXaxis; private OffsetAxis offsetYaxis; private int rotateXY; private int scaleXaxis; private int scaleYaxis; + public int getReferenceLaneId() { return referenceLaneId; } + public void setReferenceLaneId(int referenceLaneId) { this.referenceLaneId = referenceLaneId; } + public OffsetAxis getOffsetXaxis() { return offsetXaxis; } + public void setOffsetXaxis(OffsetAxis offsetXaxis) { this.offsetXaxis = offsetXaxis; } + public OffsetAxis getOffsetYaxis() { return offsetYaxis; } + public void setOffsetYaxis(OffsetAxis offsetYaxis) { this.offsetYaxis = offsetYaxis; } + public int getRotateXY() { return rotateXY; } + public void setRotateXY(int rotateXY) { this.rotateXY = rotateXY; } + public int getScaleXaxis() { return scaleXaxis; } + public void setScaleXaxis(int scaleXaxis) { this.scaleXaxis = scaleXaxis; } + public int getScaleYaxis() { return scaleYaxis; } + public void setScaleYaxis(int scaleYaxis) { this.scaleYaxis = scaleYaxis; } - + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java index 6d030422c..fa3afac19 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,40 +21,49 @@ @EqualsAndHashCode(callSuper = false) public class Content extends Asn1Object { - private static final long serialVersionUID = 1L; - private ITIS_CodesAndText advisory; - private ITIS_CodesAndText workZone; - private ITIS_CodesAndText genericSign; - private ITIS_CodesAndText speedLimit; - private ITIS_CodesAndText exitService; - + private static final long serialVersionUID = 1L; + private ITIS_CodesAndText advisory; + private ITIS_CodesAndText workZone; + private ITIS_CodesAndText genericSign; + private ITIS_CodesAndText speedLimit; + private ITIS_CodesAndText exitService; + public ITIS_CodesAndText getAdvisory() { return advisory; } + public void setAdvisory(ITIS_CodesAndText advisory) { this.advisory = advisory; } + public ITIS_CodesAndText getWorkZone() { return workZone; } + public void setWorkZone(ITIS_CodesAndText workZone) { this.workZone = workZone; } + public ITIS_CodesAndText getGenericSign() { return genericSign; } + public void setGenericSign(ITIS_CodesAndText genericSign) { this.genericSign = genericSign; } + public ITIS_CodesAndText getSpeedLimit() { return speedLimit; } + public void setSpeedLimit(ITIS_CodesAndText speedLimit) { this.speedLimit = speedLimit; } + public ITIS_CodesAndText getExitService() { return exitService; } + public void setExitService(ITIS_CodesAndText exitService) { this.exitService = exitService; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java index 28ebc62f9..984f31e95 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,29 +21,29 @@ @EqualsAndHashCode(callSuper = false) public class Description extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; + + private OffsetSystem path; - private OffsetSystem path; + private GeometricProjection geometry; - private GeometricProjection geometry; + private ValidRegion oldRegion; - private ValidRegion oldRegion; - - public OffsetSystem getPath() { - return path; - } + public OffsetSystem getPath() { + return path; + } - public void setPath(OffsetSystem path) { - this.path = path; - } + public void setPath(OffsetSystem path) { + this.path = path; + } - public GeometricProjection getGeometry() { - return geometry; - } + public GeometricProjection getGeometry() { + return geometry; + } - public void setGeometry(GeometricProjection geometry) { - this.geometry = geometry; - } + public void setGeometry(GeometricProjection geometry) { + this.geometry = geometry; + } public ValidRegion getOldRegion() { return oldRegion; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java index 1947087de..7d096a6c9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -21,7 +22,7 @@ @EqualsAndHashCode(callSuper = false) public class DirectionOfUse extends Asn1Object { private static final long serialVersionUID = 1L; - + public enum DirectionOfUseEnum { unavailable, // (0), -- unknown or NA, not typically used in valid expressions forward, // (1), -- direction of travel follows node ordering @@ -34,28 +35,35 @@ public enum DirectionOfUseEnum { private String forward; // (1), -- direction of travel follows node ordering private String reverse; // (2), -- direction of travel is the reverse of node ordering private String both; // (3) -- direction of travel allowed in both directions - + public String getUnavailable() { return unavailable; } + public void setUnavailable(String unavailable) { this.unavailable = unavailable; } + public String getForward() { return forward; } + public void setForward(String forward) { this.forward = forward; } + public String getReverse() { return reverse; } + public void setReverse(String reverse) { this.reverse = reverse; } + public String getBoth() { return both; } + public void setBoth(String both) { this.both = both; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java index 35f1232d0..07968d519 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java @@ -8,7 +8,7 @@ @EqualsAndHashCode(callSuper = false) public class DistanceUnits extends Asn1Object { private static final long serialVersionUID = 1L; - + public enum DistanceUnitsEnum { centimeter, // (0), cm2_5, // (1), -- Steps of 2.5 centimeters @@ -19,60 +19,77 @@ public enum DistanceUnitsEnum { yard, // (6), -- three US feet mile // (7) -- US mile (5280 US feet) } - + private String centimeter; // (0), - @JsonProperty("cm2-5")private String cm2_5; // (1), -- Steps of 2.5 centimeters + @JsonProperty("cm2-5") + private String cm2_5; // (1), -- Steps of 2.5 centimeters private String decimeter; // (2), private String meter; // (3), private String kilometer; // (4), private String foot; // (5), -- US foot, 0.3048 meters exactly private String yard; // (6), -- three US feet private String mile; // (7) -- US mile (5280 US feet) + public String getCentimeter() { return centimeter; } + public void setCentimeter(String centimeter) { this.centimeter = centimeter; } + public String getCm2_5() { return cm2_5; } + public void setCm2_5(String cm2_5) { this.cm2_5 = cm2_5; } + public String getDecimeter() { return decimeter; } + public void setDecimeter(String decimeter) { this.decimeter = decimeter; } + public String getMeter() { return meter; } + public void setMeter(String meter) { this.meter = meter; } + public String getKilometer() { return kilometer; } + public void setKilometer(String kilometer) { this.kilometer = kilometer; } + public String getFoot() { return foot; } + public void setFoot(String foot) { this.foot = foot; } + public String getYard() { return yard; } + public void setYard(String yard) { this.yard = yard; } + public String getMile() { return mile; } + public void setMile(String mile) { this.mile = mile; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java index bf24a9af1..a4d4a203c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java @@ -42,100 +42,131 @@ public enum ExtentEnum { private String useFor5000000meters; // (13), private String useFor10000000meters; // (14), private String forever; // (15) -- very wide area - + public String getUseInstantlyOnly() { return useInstantlyOnly; } + public void setUseInstantlyOnly(String useInstantlyOnly) { this.useInstantlyOnly = useInstantlyOnly; } + public String getUseFor3meters() { return useFor3meters; } + public void setUseFor3meters(String useFor3meters) { this.useFor3meters = useFor3meters; } + public String getUseFor10meters() { return useFor10meters; } + public void setUseFor10meters(String useFor10meters) { this.useFor10meters = useFor10meters; } + public String getUseFor50meters() { return useFor50meters; } + public void setUseFor50meters(String useFor50meters) { this.useFor50meters = useFor50meters; } + public String getUseFor100meters() { return useFor100meters; } + public void setUseFor100meters(String useFor100meters) { this.useFor100meters = useFor100meters; } + public String getUseFor500meters() { return useFor500meters; } + public void setUseFor500meters(String useFor500meters) { this.useFor500meters = useFor500meters; } + public String getUseFor1000meters() { return useFor1000meters; } + public void setUseFor1000meters(String useFor1000meters) { this.useFor1000meters = useFor1000meters; } + public String getUseFor5000meters() { return useFor5000meters; } + public void setUseFor5000meters(String useFor5000meters) { this.useFor5000meters = useFor5000meters; } + public String getUseFor10000meters() { return useFor10000meters; } + public void setUseFor10000meters(String useFor10000meters) { this.useFor10000meters = useFor10000meters; } + public String getUseFor50000meters() { return useFor50000meters; } + public void setUseFor50000meters(String useFor50000meters) { this.useFor50000meters = useFor50000meters; } + public String getUseFor100000meters() { return useFor100000meters; } + public void setUseFor100000meters(String useFor100000meters) { this.useFor100000meters = useFor100000meters; } + public String getUseFor500000meters() { return useFor500000meters; } + public void setUseFor500000meters(String useFor500000meters) { this.useFor500000meters = useFor500000meters; } + public String getUseFor1000000meters() { return useFor1000000meters; } + public void setUseFor1000000meters(String useFor1000000meters) { this.useFor1000000meters = useFor1000000meters; } + public String getUseFor5000000meters() { return useFor5000000meters; } + public void setUseFor5000000meters(String useFor5000000meters) { this.useFor5000000meters = useFor5000000meters; } + public String getUseFor10000000meters() { return useFor10000000meters; } + public void setUseFor10000000meters(String useFor10000000meters) { this.useFor10000000meters = useFor10000000meters; } + public String getForever() { return forever; } + public void setForever(String forever) { this.forever = forever; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java index 2438c1523..cb847eb4e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -21,52 +22,52 @@ @EqualsAndHashCode(callSuper = false) public class FrameType extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - public enum TravelerInfoType { - unknown, - advisory, - roadSignage, - commercialSignage - } + public enum TravelerInfoType { + unknown, + advisory, + roadSignage, + commercialSignage + } - private String advisory; + private String advisory; - private String commercialSignage; + private String commercialSignage; - private String roadSignage; + private String roadSignage; - private String unknown; + private String unknown; - public String getAdvisory() { - return advisory; - } + public String getAdvisory() { + return advisory; + } - public void setAdvisory(String advisory) { - this.advisory = advisory; - } + public void setAdvisory(String advisory) { + this.advisory = advisory; + } - public String getUnknown() { - return unknown; - } + public String getUnknown() { + return unknown; + } - public void setUnknown(String unknown) { - this.unknown = unknown; - } + public void setUnknown(String unknown) { + this.unknown = unknown; + } - public String getRoadSignage() { - return roadSignage; - } + public String getRoadSignage() { + return roadSignage; + } - public void setRoadSignage(String roadSignage) { - this.roadSignage = roadSignage; - } + public void setRoadSignage(String roadSignage) { + this.roadSignage = roadSignage; + } - public String getCommercialSignage() { - return commercialSignage; - } + public String getCommercialSignage() { + return commercialSignage; + } - public void setCommercialSignage(String commercialSignage) { - this.commercialSignage = commercialSignage; - } + public void setCommercialSignage(String commercialSignage) { + this.commercialSignage = commercialSignage; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java index b3123f274..b44636ea8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -21,50 +22,51 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "name", "id", "anchor", "laneWidth", "directionality", "closedPath", "direction", "description" }) +@JsonPropertyOrder({"name", "id", "anchor", "laneWidth", "directionality", "closedPath", + "direction", "description"}) @EqualsAndHashCode(callSuper = false) public class GeographicalPath extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @JsonProperty("name") - private String name; + @JsonProperty("name") + private String name; - @JsonProperty("id") - private Id id; + @JsonProperty("id") + private Id id; - @JsonProperty("anchor") - private Anchor anchor; + @JsonProperty("anchor") + private Anchor anchor; - @JsonProperty("laneWidth") - private String laneWidth; + @JsonProperty("laneWidth") + private String laneWidth; - @JsonProperty("directionality") - private DirectionOfUse directionality; + @JsonProperty("directionality") + private DirectionOfUse directionality; - @JsonProperty("closedPath") - private String closedPath; + @JsonProperty("closedPath") + private String closedPath; - @JsonProperty("direction") - private String direction; + @JsonProperty("direction") + private String direction; - @JsonProperty("description") - private Description description; + @JsonProperty("description") + private Description description; - public Id getId() { - return id; - } + public Id getId() { + return id; + } - public void setId(Id id) { - this.id = id; - } + public void setId(Id id) { + this.id = id; + } - public String getClosedPath() { - return closedPath; - } + public String getClosedPath() { + return closedPath; + } - public void setClosedPath(String closedPath) { - this.closedPath = closedPath; - } + public void setClosedPath(String closedPath) { + this.closedPath = closedPath; + } public DirectionOfUse getDirectionality() { @@ -75,43 +77,43 @@ public void setDirectionality(DirectionOfUse directionality) { this.directionality = directionality; } - public String getDirection() { - return direction; - } + public String getDirection() { + return direction; + } - public void setDirection(String direction) { - this.direction = direction; - } + public void setDirection(String direction) { + this.direction = direction; + } - public Description getDescription() { - return description; - } + public Description getDescription() { + return description; + } - public void setDescription(Description description) { - this.description = description; - } + public void setDescription(Description description) { + this.description = description; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setName(String name) { - this.name = name; - } + public void setName(String name) { + this.name = name; + } - public String getLaneWidth() { - return laneWidth; - } + public String getLaneWidth() { + return laneWidth; + } - public void setLaneWidth(String laneWidth) { - this.laneWidth = laneWidth; - } + public void setLaneWidth(String laneWidth) { + this.laneWidth = laneWidth; + } - public Anchor getAnchor() { - return anchor; - } + public Anchor getAnchor() { + return anchor; + } - public void setAnchor(Anchor anchor) { - this.anchor = anchor; - } + public void setAnchor(Anchor anchor) { + this.anchor = anchor; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java index 626531508..5cc27604d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -21,52 +22,52 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "direction", "extent", "laneWidth", "circle" }) +@JsonPropertyOrder({"direction", "extent", "laneWidth", "circle"}) @EqualsAndHashCode(callSuper = false) public class GeometricProjection extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - @JsonProperty("direction") - private String direction; + @JsonProperty("direction") + private String direction; - @JsonProperty("extent") - private String extent; + @JsonProperty("extent") + private String extent; - @JsonProperty("laneWidth") - private String laneWidth; + @JsonProperty("laneWidth") + private String laneWidth; - @JsonProperty("circle") - private Circle circle; + @JsonProperty("circle") + private Circle circle; - public String getExtent() { - return extent; - } + public String getExtent() { + return extent; + } - public void setExtent(String extent) { - this.extent = extent; - } + public void setExtent(String extent) { + this.extent = extent; + } - public String getDirection() { - return direction; - } + public String getDirection() { + return direction; + } - public void setDirection(String direction) { - this.direction = direction; - } + public void setDirection(String direction) { + this.direction = direction; + } - public Circle getCircle() { - return circle; - } + public Circle getCircle() { + return circle; + } - public void setCircle(Circle circle) { - this.circle = circle; - } + public void setCircle(Circle circle) { + this.circle = circle; + } - public String getLaneWidth() { - return laneWidth; - } + public String getLaneWidth() { + return laneWidth; + } - public void setLaneWidth(String laneWidth) { - this.laneWidth = laneWidth; - } + public void setLaneWidth(String laneWidth) { + this.laneWidth = laneWidth; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java index df4815bec..1fb923859 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,25 +21,25 @@ @EqualsAndHashCode(callSuper = false) public class Id extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private String region; + private String region; - private String id; + private String id; - public String getRegion() { - return region; - } + public String getRegion() { + return region; + } - public void setRegion(String region) { - this.region = region; - } + public void setRegion(String region) { + this.region = region; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public void setId(String id) { - this.id = id; - } + public void setId(String id) { + this.id = id; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java index 63db41830..3042037b9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java @@ -7,7 +7,7 @@ public class LaneDataAttribute extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java index 8ab281128..bf14a49e4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java @@ -9,11 +9,11 @@ public class LaneDataAttributeList extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - - @JsonProperty ("LaneDataAttribute") + + @JsonProperty("LaneDataAttribute") private LaneDataAttribute LaneDataAttribute; public LaneDataAttribute getLaneDataAttribute() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java index f79da2f7f..29c43a20d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,23 +21,23 @@ @EqualsAndHashCode(callSuper = false) public class MsgId extends Asn1Object { - private static final long serialVersionUID = 1L; - private RoadSignID roadSignID; - private String furtherInfoID; + private static final long serialVersionUID = 1L; + private RoadSignID roadSignID; + private String furtherInfoID; - public RoadSignID getRoadSignID() { - return roadSignID; - } + public RoadSignID getRoadSignID() { + return roadSignID; + } - public void setRoadSignID(RoadSignID roadSignID) { - this.roadSignID = roadSignID; - } + public void setRoadSignID(RoadSignID roadSignID) { + this.roadSignID = roadSignID; + } - public String getFurtherInfoID() { - return furtherInfoID; - } + public String getFurtherInfoID() { + return furtherInfoID; + } - public void setFurtherInfoID(String furtherInfoID) { - this.furtherInfoID = furtherInfoID; - } + public void setFurtherInfoID(String furtherInfoID) { + this.furtherInfoID = furtherInfoID; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java index bdb879636..5abfcf453 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java @@ -7,10 +7,10 @@ public class NodeAttributeSetXY extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - + // localNode NodeAttributeXYList OPTIONAL, // -- Attribute states which pertain to this node point // disabled SegmentAttributeXYList OPTIONAL, @@ -33,7 +33,7 @@ public class NodeAttributeSetXY extends Asn1Object { // -- at this node from this node onwards, in 10cm steps // -- elevations between nodes are a linear taper between pts // -- the value of zero shall not be sent here - + private LaneDataAttributeList data; public LaneDataAttributeList getData() { @@ -44,5 +44,5 @@ public void setData(LaneDataAttributeList data) { this.data = data; } - + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java index 3a0545c09..c718bb993 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java @@ -1,36 +1,34 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @EqualsAndHashCode(callSuper = false) -public class NodeLL extends Asn1Object -{ - private static final long serialVersionUID = 1L; - private NodeOffsetPointXY delta; +public class NodeLL extends Asn1Object { + private static final long serialVersionUID = 1L; + private NodeOffsetPointXY delta; - public NodeOffsetPointXY getDelta () - { - return delta; - } + public NodeOffsetPointXY getDelta() { + return delta; + } - public void setDelta (NodeOffsetPointXY delta) - { - this.delta = delta; - } + public void setDelta(NodeOffsetPointXY delta) { + this.delta = delta; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java index 4ff06599d..6c0afd3f4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java @@ -1,37 +1,35 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @EqualsAndHashCode(callSuper = false) -public class NodeListLL extends Asn1Object -{ - private static final long serialVersionUID = 1L; - private Nodes nodes; +public class NodeListLL extends Asn1Object { + private static final long serialVersionUID = 1L; + private Nodes nodes; - public Nodes getNodes () - { - return nodes; - } + public Nodes getNodes() { + return nodes; + } - public void setNodes (Nodes nodes) - { - this.nodes = nodes; - } + public void setNodes(Nodes nodes) { + this.nodes = nodes; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java index 41a2d9387..8fb7cf1e0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java @@ -9,19 +9,22 @@ public class NodeListXY extends Asn1Object { private NodeSetXY nodes; private ComputedLane computed; - + public NodeSetXY getNodes() { return nodes; } + public void setNodes(NodeSetXY nodes) { this.nodes = nodes; } + public ComputedLane getComputed() { return computed; } + public void setComputed(ComputedLane computed) { this.computed = computed; } - - + + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java index 5f40820d0..d62d47bb7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -23,160 +24,160 @@ @EqualsAndHashCode(callSuper = false) public class NodeOffsetPointXY extends Asn1Object { - private static final long serialVersionUID = 1L; - - @JsonProperty("node-XY") - private Node_XY node_XY; - - @JsonProperty("node-XY1") - private Node_XY node_XY1; + private static final long serialVersionUID = 1L; + + @JsonProperty("node-XY") + private Node_XY node_XY; + + @JsonProperty("node-XY1") + private Node_XY node_XY1; - @JsonProperty("node-XY2") - private Node_XY node_XY2; + @JsonProperty("node-XY2") + private Node_XY node_XY2; - @JsonProperty("node-XY3") - private Node_XY node_XY3; + @JsonProperty("node-XY3") + private Node_XY node_XY3; - @JsonProperty("node-XY4") - private Node_XY node_XY4; + @JsonProperty("node-XY4") + private Node_XY node_XY4; - @JsonProperty("node-XY5") - private Node_XY node_XY5; + @JsonProperty("node-XY5") + private Node_XY node_XY5; - @JsonProperty("node-XY6") - private Node_XY node_XY6; + @JsonProperty("node-XY6") + private Node_XY node_XY6; - @JsonProperty("node-LL1") - private Node_LatLon node_LL1; + @JsonProperty("node-LL1") + private Node_LatLon node_LL1; - @JsonProperty("node-LL2") - private Node_LatLon node_LL2; + @JsonProperty("node-LL2") + private Node_LatLon node_LL2; - @JsonProperty("node-LL3") - private Node_LatLon node_LL3; + @JsonProperty("node-LL3") + private Node_LatLon node_LL3; - @JsonProperty("node-LL4") - private Node_LatLon node_LL4; + @JsonProperty("node-LL4") + private Node_LatLon node_LL4; - @JsonProperty("node-LL5") - private Node_LatLon node_LL5; + @JsonProperty("node-LL5") + private Node_LatLon node_LL5; - @JsonProperty("node-LL6") - private Node_LatLon node_LL6; + @JsonProperty("node-LL6") + private Node_LatLon node_LL6; - @JsonProperty("node-LatLon") - private Node_LatLon node_LatLon; + @JsonProperty("node-LatLon") + private Node_LatLon node_LatLon; - public Node_XY getNode_XY() { - return node_XY; - } + public Node_XY getNode_XY() { + return node_XY; + } - public void setNode_XY(Node_XY node_XY) { - this.node_XY = node_XY; - } + public void setNode_XY(Node_XY node_XY) { + this.node_XY = node_XY; + } - public Node_XY getNode_XY1() { - return node_XY1; - } + public Node_XY getNode_XY1() { + return node_XY1; + } - public void setNode_XY1(Node_XY node_XY1) { - this.node_XY1 = node_XY1; - } + public void setNode_XY1(Node_XY node_XY1) { + this.node_XY1 = node_XY1; + } - public Node_XY getNode_XY2() { - return node_XY2; - } + public Node_XY getNode_XY2() { + return node_XY2; + } - public void setNode_XY2(Node_XY node_XY2) { - this.node_XY2 = node_XY2; - } + public void setNode_XY2(Node_XY node_XY2) { + this.node_XY2 = node_XY2; + } - public Node_XY getNode_XY3() { - return node_XY3; - } + public Node_XY getNode_XY3() { + return node_XY3; + } - public void setNode_XY3(Node_XY node_XY3) { - this.node_XY3 = node_XY3; - } + public void setNode_XY3(Node_XY node_XY3) { + this.node_XY3 = node_XY3; + } - public Node_XY getNode_XY4() { - return node_XY4; - } + public Node_XY getNode_XY4() { + return node_XY4; + } - public void setNode_XY4(Node_XY node_XY4) { - this.node_XY4 = node_XY4; - } + public void setNode_XY4(Node_XY node_XY4) { + this.node_XY4 = node_XY4; + } - public Node_XY getNode_XY5() { - return node_XY5; - } + public Node_XY getNode_XY5() { + return node_XY5; + } - public void setNode_XY5(Node_XY node_XY5) { - this.node_XY5 = node_XY5; - } + public void setNode_XY5(Node_XY node_XY5) { + this.node_XY5 = node_XY5; + } - public Node_XY getNode_XY6() { - return node_XY6; - } + public Node_XY getNode_XY6() { + return node_XY6; + } - public void setNode_XY6(Node_XY node_XY6) { - this.node_XY6 = node_XY6; - } + public void setNode_XY6(Node_XY node_XY6) { + this.node_XY6 = node_XY6; + } - public Node_LatLon getNode_LL1() { - return node_LL1; - } + public Node_LatLon getNode_LL1() { + return node_LL1; + } - public void setNode_LL1(Node_LatLon node_LL1) { - this.node_LL1 = node_LL1; - } + public void setNode_LL1(Node_LatLon node_LL1) { + this.node_LL1 = node_LL1; + } - public Node_LatLon getNode_LL2() { - return node_LL2; - } + public Node_LatLon getNode_LL2() { + return node_LL2; + } - public void setNode_LL2(Node_LatLon node_LL2) { - this.node_LL2 = node_LL2; - } + public void setNode_LL2(Node_LatLon node_LL2) { + this.node_LL2 = node_LL2; + } - public Node_LatLon getNode_LL3() { - return node_LL3; - } + public Node_LatLon getNode_LL3() { + return node_LL3; + } - public void setNode_LL3(Node_LatLon node_LL3) { - this.node_LL3 = node_LL3; - } + public void setNode_LL3(Node_LatLon node_LL3) { + this.node_LL3 = node_LL3; + } - public Node_LatLon getNode_LL4() { - return node_LL4; - } + public Node_LatLon getNode_LL4() { + return node_LL4; + } - public void setNode_LL4(Node_LatLon node_LL4) { - this.node_LL4 = node_LL4; - } + public void setNode_LL4(Node_LatLon node_LL4) { + this.node_LL4 = node_LL4; + } - public Node_LatLon getNode_LL5() { - return node_LL5; - } + public Node_LatLon getNode_LL5() { + return node_LL5; + } - public void setNode_LL5(Node_LatLon node_LL5) { - this.node_LL5 = node_LL5; - } + public void setNode_LL5(Node_LatLon node_LL5) { + this.node_LL5 = node_LL5; + } - public Node_LatLon getNode_LL6() { - return node_LL6; - } + public Node_LatLon getNode_LL6() { + return node_LL6; + } - public void setNode_LL6(Node_LatLon node_LL6) { - this.node_LL6 = node_LL6; - } + public void setNode_LL6(Node_LatLon node_LL6) { + this.node_LL6 = node_LL6; + } - public Node_LatLon getNode_LatLon() { - return node_LatLon; - } + public Node_LatLon getNode_LatLon() { + return node_LatLon; + } - public void setNode_LatLon(Node_LatLon node_LatLon) { - this.node_LatLon = node_LatLon; - } + public void setNode_LatLon(Node_LatLon node_LatLon) { + this.node_LatLon = node_LatLon; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java index 2a731532e..c1e874f03 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java @@ -10,7 +10,7 @@ public class NodeSetXY extends Asn1Object { private static final long serialVersionUID = 1L; private NodeXY[] NodeXY; - + @JsonProperty("NodeXY") public NodeXY[] getNodeXY() { return NodeXY; @@ -19,6 +19,6 @@ public NodeXY[] getNodeXY() { public void setNodeXY(NodeXY[] nodeXY) { this.NodeXY = nodeXY; } - - + + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java index a472f9410..04c9960e9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java index 99d22af65..1fc69223d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,26 +21,26 @@ @EqualsAndHashCode(callSuper = false) public class Node_XY extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private String x; + private String x; - private String y; + private String y; - public String getX() { - return x; - } + public String getX() { + return x; + } - public void setX(String x) { - this.x = x; - } + public void setX(String x) { + this.x = x; + } - public String getY() { - return y; - } + public String getY() { + return y; + } - public void setY(String y) { - this.y = y; - } + public void setY(String y) { + this.y = y; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java index 33ed12add..acbb56e9f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; @@ -23,23 +24,23 @@ @EqualsAndHashCode(callSuper = false) public class Nodes extends Asn1Object { - private static final long serialVersionUID = 1L; - private NodeLL[] nodeLL; - - @JsonProperty("NodeXY") - private NodeXY[] nodeXY; - - @JsonProperty("NodeLL") - public NodeLL[] getNodeLL() { - return nodeLL; - } - - public void setNodeLL(NodeLL[] NodeLL) { - this.nodeLL = NodeLL; - } - - @Override - public String toString() { - return "ClassPojo [NodeLL = " + nodeLL + "]"; - } + private static final long serialVersionUID = 1L; + private NodeLL[] nodeLL; + + @JsonProperty("NodeXY") + private NodeXY[] nodeXY; + + @JsonProperty("NodeLL") + public NodeLL[] getNodeLL() { + return nodeLL; + } + + public void setNodeLL(NodeLL[] NodeLL) { + this.nodeLL = NodeLL; + } + + @Override + public String toString() { + return "ClassPojo [NodeLL = " + nodeLL + "]"; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java index da359618c..99c9d6450 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java index 9441fa25d..e2bebe3f1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,26 +21,26 @@ @EqualsAndHashCode(callSuper = false) public class OffsetAxis extends Asn1Object { - private static final long serialVersionUID = 7703530986729802700L; + private static final long serialVersionUID = 7703530986729802700L; + + private Integer small; - private Integer small; - - private Integer large; + private Integer large; - public Integer getSmall() { - return small; - } + public Integer getSmall() { + return small; + } - public void setSmall(Integer small) { - this.small = small; - } + public void setSmall(Integer small) { + this.small = small; + } - public Integer getLarge() { - return large; - } + public Integer getLarge() { + return large; + } - public void setLarge(Integer large) { - this.large = large; - } + public void setLarge(Integer large) { + this.large = large; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java index 926810005..864a21a78 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import lombok.EqualsAndHashCode; @@ -20,25 +21,25 @@ @EqualsAndHashCode(callSuper = false) public class OffsetSystem extends Asn1Object { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; - private String scale; + private String scale; - private Offset offset; + private Offset offset; - public String getScale() { - return scale; - } + public String getScale() { + return scale; + } - public void setScale(String scale) { - this.scale = scale; - } + public void setScale(String scale) { + this.scale = scale; + } - public Offset getOffset() { - return offset; - } + public Offset getOffset() { + return offset; + } - public void setOffset(Offset offset) { - this.offset = offset; - } + public void setOffset(Offset offset) { + this.offset = offset; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java index 81507aabd..696ffabce 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -23,39 +24,39 @@ import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; @JsonIgnoreProperties(ignoreUnknown = true) -@JsonPropertyOrder({ "lat", "llong", "elevation" }) +@JsonPropertyOrder({"lat", "llong", "elevation"}) @EqualsAndHashCode(callSuper = false) public class Position extends Asn1Object { - private static final long serialVersionUID = 1L; - - @JsonProperty("lat") - private String lat; - @JsonProperty("long") - private String llong; - @JsonProperty("elevation") - private String elevation; - - public String getElevation() { - return elevation; - } - - public void setElevation(String elevation) { - this.elevation = elevation; - } - - public String getLlong() { - return llong; - } - - public void setLlong(String lon) { - this.llong = lon; - } - - public String getLat() { - return lat; - } - - public void setLat(String lat) { - this.lat = lat; - } + private static final long serialVersionUID = 1L; + + @JsonProperty("lat") + private String lat; + @JsonProperty("long") + private String llong; + @JsonProperty("elevation") + private String elevation; + + public String getElevation() { + return elevation; + } + + public void setElevation(String elevation) { + this.elevation = elevation; + } + + public String getLlong() { + return llong; + } + + public void setLlong(String lon) { + this.llong = lon; + } + + public String getLat() { + return lat; + } + + public void setLat(String lat) { + this.lat = lat; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java index 221d468a9..ea9a7e20d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java @@ -6,7 +6,7 @@ @EqualsAndHashCode(callSuper = false) public class RegionList extends Asn1Object { private static final long serialVersionUID = 1L; - + private RegionOffsets[] nodeList; public RegionOffsets[] getNodeList() { @@ -16,6 +16,6 @@ public RegionOffsets[] getNodeList() { public void setNodeList(RegionOffsets[] nodeList) { this.nodeList = nodeList; } - - + + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java index aff1f37dd..61d4b3ac6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java @@ -6,28 +6,34 @@ @EqualsAndHashCode(callSuper = false) public class RegionOffsets extends Asn1Object { private static final long serialVersionUID = 1L; - + private int xOffset; private int yOffset; private int zOffset; + public int getxOffset() { return xOffset; } + public void setxOffset(int xOffset) { this.xOffset = xOffset; } + public int getyOffset() { return yOffset; } + public void setyOffset(int yOffset) { this.yOffset = yOffset; } + public int getzOffset() { return zOffset; } + public void setzOffset(int zOffset) { this.zOffset = zOffset; } - - + + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java index f80c56793..94c6701b1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java @@ -6,29 +6,34 @@ @EqualsAndHashCode(callSuper = false) public class RegionPointSet extends Asn1Object { private static final long serialVersionUID = 1L; - + private Position anchor; private int scale; private RegionList regionList; - + public Position getAnchor() { return anchor; } + public void setAnchor(Position anchor) { this.anchor = anchor; } + public int getScale() { return scale; } + public void setScale(int scale) { this.scale = scale; } + public RegionList getRegionList() { return regionList; } + public void setRegionList(RegionList regionList) { this.regionList = regionList; } - + } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java index 513f2c6be..f5e6e06c9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java index bb705e2a4..28c5732df 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java @@ -7,22 +7,25 @@ public class RegulatorySpeedLimit extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - + private SpeedLimitType type; private int speed; - + public SpeedLimitType getType() { return type; } + public void setType(SpeedLimitType type) { this.type = type; } + public int getSpeed() { return speed; } + public void setSpeed(int speed) { this.speed = speed; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java index b7359e1ee..c751c1839 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java @@ -6,33 +6,40 @@ @EqualsAndHashCode(callSuper = false) public class ShapePointSet extends Asn1Object { private static final long serialVersionUID = 1L; - + private Position anchor; private int laneWidth; private DirectionOfUse directionality; private NodeListXY nodeList; - + public Position getAnchor() { return anchor; } + public void setAnchor(Position anchor) { this.anchor = anchor; } + public int getLaneWidth() { return laneWidth; } + public void setLaneWidth(int laneWidth) { this.laneWidth = laneWidth; } + public DirectionOfUse getDirectionality() { return directionality; } + public void setDirectionality(DirectionOfUse directionality) { this.directionality = directionality; } + public NodeListXY getNodeList() { return nodeList; } + public void setNodeList(NodeListXY nodeList) { this.nodeList = nodeList; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java index e0c64711c..275160df6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java @@ -9,10 +9,10 @@ public class SpeedLimitList extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - + @JsonProperty("RegulatorySpeedLimit") private RegulatorySpeedLimit[] RegulatorySpeedLimit; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java index 9d8af8d2c..c4942ac4d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java @@ -7,16 +7,16 @@ public class SpeedLimitType extends Asn1Object { /** - * + * */ private static final long serialVersionUID = 1L; - + public enum SpeedLimitTypeEnum { unknown, //-- Speed limit type not available maxSpeedInSchoolZone, //-- Only sent when the limit is active maxSpeedInSchoolZoneWhenChildrenArePresent, //-- Sent at any time maxSpeedInConstructionZone, //-- Used for work zones, incident zones, etc. - //-- where a reduced speed is present + //-- where a reduced speed is present vehicleMinSpeed, vehicleMaxSpeed, //-- Regulatory speed limit for general traffic vehicleNightMaxSpeed, @@ -41,81 +41,108 @@ public enum SpeedLimitTypeEnum { private String vehiclesWithTrailersMinSpeed; private String vehiclesWithTrailersMaxSpeed; private String vehiclesWithTrailersNightMaxSpeed; + public String getUnknown() { return unknown; } + public void setUnknown(String unknown) { this.unknown = unknown; } + public String getMaxSpeedInSchoolZone() { return maxSpeedInSchoolZone; } + public void setMaxSpeedInSchoolZone(String maxSpeedInSchoolZone) { this.maxSpeedInSchoolZone = maxSpeedInSchoolZone; } + public String getMaxSpeedInSchoolZoneWhenChildrenArePresent() { return maxSpeedInSchoolZoneWhenChildrenArePresent; } - public void setMaxSpeedInSchoolZoneWhenChildrenArePresent(String maxSpeedInSchoolZoneWhenChildrenArePresent) { + + public void setMaxSpeedInSchoolZoneWhenChildrenArePresent( + String maxSpeedInSchoolZoneWhenChildrenArePresent) { this.maxSpeedInSchoolZoneWhenChildrenArePresent = maxSpeedInSchoolZoneWhenChildrenArePresent; } + public String getMaxSpeedInConstructionZone() { return maxSpeedInConstructionZone; } + public void setMaxSpeedInConstructionZone(String maxSpeedInConstructionZone) { this.maxSpeedInConstructionZone = maxSpeedInConstructionZone; } + public String getVehicleMinSpeed() { return vehicleMinSpeed; } + public void setVehicleMinSpeed(String vehicleMinSpeed) { this.vehicleMinSpeed = vehicleMinSpeed; } + public String getVehicleMaxSpeed() { return vehicleMaxSpeed; } + public void setVehicleMaxSpeed(String vehicleMaxSpeed) { this.vehicleMaxSpeed = vehicleMaxSpeed; } + public String getVehicleNightMaxSpeed() { return vehicleNightMaxSpeed; } + public void setVehicleNightMaxSpeed(String vehicleNightMaxSpeed) { this.vehicleNightMaxSpeed = vehicleNightMaxSpeed; } + public String getTruckMinSpeed() { return truckMinSpeed; } + public void setTruckMinSpeed(String truckMinSpeed) { this.truckMinSpeed = truckMinSpeed; } + public String getTruckMaxSpeed() { return truckMaxSpeed; } + public void setTruckMaxSpeed(String truckMaxSpeed) { this.truckMaxSpeed = truckMaxSpeed; } + public String getTruckNightMaxSpeed() { return truckNightMaxSpeed; } + public void setTruckNightMaxSpeed(String truckNightMaxSpeed) { this.truckNightMaxSpeed = truckNightMaxSpeed; } + public String getVehiclesWithTrailersMinSpeed() { return vehiclesWithTrailersMinSpeed; } + public void setVehiclesWithTrailersMinSpeed(String vehiclesWithTrailersMinSpeed) { this.vehiclesWithTrailersMinSpeed = vehiclesWithTrailersMinSpeed; } + public String getVehiclesWithTrailersMaxSpeed() { return vehiclesWithTrailersMaxSpeed; } + public void setVehiclesWithTrailersMaxSpeed(String vehiclesWithTrailersMaxSpeed) { this.vehiclesWithTrailersMaxSpeed = vehiclesWithTrailersMaxSpeed; } + public String getVehiclesWithTrailersNightMaxSpeed() { return vehiclesWithTrailersNightMaxSpeed; } + public void setVehiclesWithTrailersNightMaxSpeed(String vehiclesWithTrailersNightMaxSpeed) { this.vehiclesWithTrailersNightMaxSpeed = vehiclesWithTrailersNightMaxSpeed; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java index e2948257d..860be692d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java @@ -1,18 +1,19 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonAlias; @@ -23,142 +24,143 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -@JsonPropertyOrder({ "doNotUse1", "frameType", "msgId", "startYear", "startTime", "durationTime", "priority", - "doNotUse2", "regions", "doNotUse3", "doNotUse4", "tcontent", "url" }) +@JsonPropertyOrder({"doNotUse1", "frameType", "msgId", "startYear", "startTime", "durationTime", + "priority", + "doNotUse2", "regions", "doNotUse3", "doNotUse4", "tcontent", "url"}) @EqualsAndHashCode(callSuper = false) public class TravelerDataFrame extends Asn1Object { - private static final long serialVersionUID = 1L; - @JsonAlias({"sspTimRights", "notUsed"}) - private String doNotUse1; - private FrameType frameType; - private MsgId msgId; - private String startYear; - private String startTime; - @JsonAlias("duratonTime") - private String durationTime; - private String priority; - @JsonAlias({"sspLocationRights", "notUsed1"}) - private String doNotUse2; - private Regions regions; - @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) - private String doNotUse3; - @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) - private String doNotUse4; - @JsonProperty("tcontent") - private Content tcontent; - private String url; - - public String getDoNotUse2() { - return doNotUse2; - } - - public void setDoNotUse2(String doNotUse2) { - this.doNotUse2 = doNotUse2; - } - - - public Regions getRegions() { - return regions; - } - - public void setRegions(Regions regions) { - this.regions = regions; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public FrameType getFrameType() { - return frameType; - } - - public void setFrameType(FrameType frameType) { - this.frameType = frameType; - } - - public String getDurationTime() { - return durationTime; - } - - public void setDurationTime(String duratonTime) { - this.durationTime = duratonTime; - } - - @JsonIgnore - public Content getContent() { - return tcontent; - } - - public Content getTcontent() { - return tcontent; - } - - public void setTcontent(Content tcontent) { - this.tcontent = tcontent; - } - - public void setContent(Content content) { - this.tcontent = content; - } - - public String getStartTime() { - return startTime; - } - - public void setStartTime(String startTime) { - this.startTime = startTime; - } - - public String getStartYear() { - return startYear; - } - - public void setStartYear(String startYear) { - this.startYear = startYear; - } - - public String getPriority() { - return priority; - } - - public void setPriority(String priority) { - this.priority = priority; - } - - public MsgId getMsgId() { - return msgId; - } - - public void setMsgId(MsgId msgId) { - this.msgId = msgId; - } - - public String getDoNotUse4() { - return doNotUse4; - } - - public void setDoNotUse4(String doNotUse4) { - this.doNotUse4 = doNotUse4; - } + private static final long serialVersionUID = 1L; + @JsonAlias({"sspTimRights", "notUsed"}) + private String doNotUse1; + private FrameType frameType; + private MsgId msgId; + private String startYear; + private String startTime; + @JsonAlias("duratonTime") + private String durationTime; + private String priority; + @JsonAlias({"sspLocationRights", "notUsed1"}) + private String doNotUse2; + private Regions regions; + @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) + private String doNotUse3; + @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) + private String doNotUse4; + @JsonProperty("tcontent") + private Content tcontent; + private String url; + + public String getDoNotUse2() { + return doNotUse2; + } + + public void setDoNotUse2(String doNotUse2) { + this.doNotUse2 = doNotUse2; + } + + + public Regions getRegions() { + return regions; + } + + public void setRegions(Regions regions) { + this.regions = regions; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public FrameType getFrameType() { + return frameType; + } + + public void setFrameType(FrameType frameType) { + this.frameType = frameType; + } + + public String getDurationTime() { + return durationTime; + } + + public void setDurationTime(String duratonTime) { + this.durationTime = duratonTime; + } + + @JsonIgnore + public Content getContent() { + return tcontent; + } + + public Content getTcontent() { + return tcontent; + } + + public void setTcontent(Content tcontent) { + this.tcontent = tcontent; + } + + public void setContent(Content content) { + this.tcontent = content; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getStartYear() { + return startYear; + } + + public void setStartYear(String startYear) { + this.startYear = startYear; + } + + public String getPriority() { + return priority; + } + + public void setPriority(String priority) { + this.priority = priority; + } + + public MsgId getMsgId() { + return msgId; + } + + public void setMsgId(MsgId msgId) { + this.msgId = msgId; + } + + public String getDoNotUse4() { + return doNotUse4; + } + + public void setDoNotUse4(String doNotUse4) { + this.doNotUse4 = doNotUse4; + } - public String getDoNotUse1() { - return doNotUse1; - } + public String getDoNotUse1() { + return doNotUse1; + } - public void setDoNotUse1(String doNotUse1) { - this.doNotUse1 = doNotUse1; - } + public void setDoNotUse1(String doNotUse1) { + this.doNotUse1 = doNotUse1; + } - public String getDoNotUse3() { - return doNotUse3; - } - - public void setDoNotUse3(String doNotUse3) { - this.doNotUse3 = doNotUse3; - } + public String getDoNotUse3() { + return doNotUse3; + } + + public void setDoNotUse3(String doNotUse3) { + this.doNotUse3 = doNotUse3; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java index dfc0b22bd..c47b36c47 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java @@ -10,22 +10,27 @@ public class ValidRegion extends Asn1Object { private String direction; private Extent extent; private Area area; - + public String getDirection() { return direction; } + public void setDirection(String direction) { this.direction = direction; } + public Extent getExtent() { return extent; } + public void setExtent(Extent extent) { this.extent = extent; } + public Area getArea() { return area; } + public void setArea(Area area) { this.area = area; } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java index 122b5a989..aa3f1b771 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java @@ -12,7 +12,8 @@ class TravelerDataFrameTest { @Test void deserializePreJ2735_2016() throws IOException { - String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json"))); + String json = new String(Files.readAllBytes(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json"))); ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); @@ -23,7 +24,8 @@ void deserializePreJ2735_2016() throws IOException { @Test void deserializeJ2735_2016() throws IOException { - String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json"))); + String json = new String(Files.readAllBytes(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json"))); ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); @@ -34,7 +36,8 @@ void deserializeJ2735_2016() throws IOException { @Test void deserializeJ2735_2020() throws IOException { - String json = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json"))); + String json = new String(Files.readAllBytes(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json"))); ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 059a6f18d..6736bb089 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -1,22 +1,25 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.traveler; import org.apache.commons.io.IOUtils; + import static org.junit.Assert.assertEquals; + import org.junit.jupiter.api.Test; import org.springframework.http.ResponseEntity; @@ -44,162 +47,184 @@ public class TimDepositControllerTest { - @Tested - TimDepositController testTimDepositController; - - @Injectable - OdeKafkaProperties injectableOdeKafkaProperties; - - @Injectable - Asn1CoderTopics injectableAsn1CoderTopics; - - @Injectable - PojoTopics injectablePojoTopics; - - @Injectable - JsonTopics injectableJsonTopics; - - @Injectable - TimIngestTrackerProperties injectableTimIngestTrackerProperties; - - @Injectable - SecurityServicesProperties injectableSecurityServicesProperties; - - @Capturing - MessageProducer capturingMessageProducer; - - @Test - public void nullRequestShouldReturnEmptyError() { - ResponseEntity actualResponse = testTimDepositController.postTim(null); - assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); - } - - @Test - public void emptyRequestShouldReturnEmptyError() { - ResponseEntity actualResponse = testTimDepositController.postTim(""); - assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); - } - - @Test - public void invalidJsonSyntaxShouldReturnJsonSyntaxError() { - ResponseEntity actualResponse = testTimDepositController.postTim("{\"in\"va}}}on\"}}"); - assertEquals("{\"error\":\"Malformed or non-compliant JSON syntax.\"}", actualResponse.getBody()); - } - - @Test - public void missingRequestElementShouldReturnMissingRequestError() { - ResponseEntity actualResponse = testTimDepositController.postTim("{\"tim\":{}}"); - assertEquals("{\"error\":\"Missing or invalid argument: Request element is required as of version 3.\"}", - actualResponse.getBody()); - } - - @Test - public void invalidTimestampShouldReturnInvalidTimestampError() { - ResponseEntity actualResponse = testTimDepositController - .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"201-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"error\":\"Invalid timestamp in tim record: 201-03-13T01:07:11-05:00\"}", - actualResponse.getBody()); - } - - @Test - public void messageWithNoRSUsOrSDWShouldReturnWarning() { - ResponseEntity actualResponse = testTimDepositController - .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"2018-03-13T01:07:11-05:00\"}}"); - assertEquals( - "{\"warning\":\"Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams.\"}", - actualResponse.getBody()); - } - - @Test - public void failedObjectNodeConversionShouldReturnConvertingError( - @Capturing TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) - throws JsonUtilsException { - - new Expectations() { - - { - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim((JsonNode) any); - result = new JsonUtilsException("testException123", null); - } - }; - - ResponseEntity actualResponse = testTimDepositController.postTim( - "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"error\":\"Error converting to encodable TravelerInputData.\"}", actualResponse.getBody()); - } - - @Test - public void failedXmlConversionShouldReturnConversionError(@Capturing TimTransmogrifier capturingTimTransmogrifier) - throws XmlUtilsException, JsonUtilsException { - - new Expectations() { - { - TimTransmogrifier.convertToXml((DdsAdvisorySituationData) any, (ObjectNode) any, (OdeMsgMetadata) any, - (SerialId) any); - result = new XmlUtilsException("testException123", null); - } - }; - - ResponseEntity actualResponse = testTimDepositController.postTim( - "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"error\":\"Error sending data to ASN.1 Encoder module: testException123\"}", - actualResponse.getBody()); - - } - - @Test - public void testSuccessfulMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - ResponseEntity actualResponse = testTimDepositController.postTim( - "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } - - @Test - public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() - throws Exception { - String file = "/sdwRequest.json"; - String json = IOUtils.toString( - TimDepositControllerTest.class.getResourceAsStream(file), - "UTF-8"); - ResponseEntity actualResponse = testTimDepositController.postTim(json); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } - - @Test - public void testSuccessfulMessageReturnsSuccessMessagePostWithOde(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - ResponseEntity actualResponse = testTimDepositController.postTim( - "{\"request\":{\"ode\":{},\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } - - @Test - public void testSuccessfulMessageReturnsSuccessMessagePut(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - ResponseEntity actualResponse = testTimDepositController.putTim( - "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } - - @Test - public void testDepositingTimWithExtraProperties(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - String timToSubmit = "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; - ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } - - @Test - public void testSuccessfulTimIngestIsTracked(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - String timToSubmit = "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; - long priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); - ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived()); - } - - @Test - public void testSuccessfulRsuMessageReturnsSuccessMessagePost(@Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { - String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"doNotUse2\": 0, \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; - ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); - assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); - } + @Tested + TimDepositController testTimDepositController; + + @Injectable + OdeKafkaProperties injectableOdeKafkaProperties; + + @Injectable + Asn1CoderTopics injectableAsn1CoderTopics; + + @Injectable + PojoTopics injectablePojoTopics; + + @Injectable + JsonTopics injectableJsonTopics; + + @Injectable + TimIngestTrackerProperties injectableTimIngestTrackerProperties; + + @Injectable + SecurityServicesProperties injectableSecurityServicesProperties; + + @Capturing + MessageProducer capturingMessageProducer; + + @Test + public void nullRequestShouldReturnEmptyError() { + ResponseEntity actualResponse = testTimDepositController.postTim(null); + assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); + } + + @Test + public void emptyRequestShouldReturnEmptyError() { + ResponseEntity actualResponse = testTimDepositController.postTim(""); + assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); + } + + @Test + public void invalidJsonSyntaxShouldReturnJsonSyntaxError() { + ResponseEntity actualResponse = testTimDepositController.postTim("{\"in\"va}}}on\"}}"); + assertEquals("{\"error\":\"Malformed or non-compliant JSON syntax.\"}", + actualResponse.getBody()); + } + + @Test + public void missingRequestElementShouldReturnMissingRequestError() { + ResponseEntity actualResponse = testTimDepositController.postTim("{\"tim\":{}}"); + assertEquals( + "{\"error\":\"Missing or invalid argument: Request element is required as of version 3.\"}", + actualResponse.getBody()); + } + + @Test + public void invalidTimestampShouldReturnInvalidTimestampError() { + ResponseEntity actualResponse = testTimDepositController + .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"201-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"error\":\"Invalid timestamp in tim record: 201-03-13T01:07:11-05:00\"}", + actualResponse.getBody()); + } + + @Test + public void messageWithNoRSUsOrSDWShouldReturnWarning() { + ResponseEntity actualResponse = testTimDepositController + .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"2018-03-13T01:07:11-05:00\"}}"); + assertEquals( + "{\"warning\":\"Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams.\"}", + actualResponse.getBody()); + } + + @Test + public void failedObjectNodeConversionShouldReturnConvertingError( + @Capturing + TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) + throws JsonUtilsException { + + new Expectations() { + + { + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim( + (JsonNode) any); + result = new JsonUtilsException("testException123", null); + } + }; + + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"error\":\"Error converting to encodable TravelerInputData.\"}", + actualResponse.getBody()); + } + + @Test + public void failedXmlConversionShouldReturnConversionError( + @Capturing TimTransmogrifier capturingTimTransmogrifier) + throws XmlUtilsException, JsonUtilsException { + + new Expectations() { + { + TimTransmogrifier.convertToXml((DdsAdvisorySituationData) any, (ObjectNode) any, + (OdeMsgMetadata) any, + (SerialId) any); + result = new XmlUtilsException("testException123", null); + } + }; + + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"error\":\"Error sending data to ASN.1 Encoder module: testException123\"}", + actualResponse.getBody()); + + } + + @Test + public void testSuccessfulMessageReturnsSuccessMessagePost( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } + + @Test + public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() + throws Exception { + String file = "/sdwRequest.json"; + String json = IOUtils.toString( + TimDepositControllerTest.class.getResourceAsStream(file), + "UTF-8"); + ResponseEntity actualResponse = testTimDepositController.postTim(json); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } + + @Test + public void testSuccessfulMessageReturnsSuccessMessagePostWithOde( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{\"ode\":{},\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } + + @Test + public void testSuccessfulMessageReturnsSuccessMessagePut( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + ResponseEntity actualResponse = testTimDepositController.putTim( + "{\"request\":{\"rsus\":[],\"snmp\":{}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\"}}"); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } + + @Test + public void testDepositingTimWithExtraProperties( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + String timToSubmit = + "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; + ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } + + @Test + public void testSuccessfulTimIngestIsTracked( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + String timToSubmit = + "{\"request\":{\"rsus\":[],\"snmp\":{},\"randomProp1\":true,\"randomProp2\":\"hello world\"},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"randomProp3\":123,\"randomProp4\":{\"nestedProp1\":\"foo\",\"nestedProp2\":\"bar\"}}}"; + long priorIngestCount = TimIngestTracker.getInstance().getTotalMessagesReceived(); + ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + assertEquals(priorIngestCount + 1, TimIngestTracker.getInstance().getTotalMessagesReceived()); + } + + @Test + public void testSuccessfulRsuMessageReturnsSuccessMessagePost( + @Capturing TimTransmogrifier capturingTimTransmogrifier, + @Capturing XmlUtils capturingXmlUtils) { + String timToSubmit = + "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"doNotUse2\": 0, \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; + ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); + assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index a7d52097c..0f9b25a14 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -49,317 +49,349 @@ @EnableConfigurationProperties(value = RsuProperties.class) class TimTransmogrifierTest { - @Autowired - RsuProperties rsuProperties; - - private static final String schemaVersion = "7"; - - @Test - void testUpdateRsuCreds_UpdateWhenNull() { - RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); - - RSU actual = new RSU("127.0.0.1", null, null, 1, 2000); - TimTransmogrifier.updateRsuCreds(actual, rsuProperties); - - assertEquals(expected, actual); - } - - @Test - void testUpdateRsuCreds_DoNotOverwriteExisting() { - RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); - - RSU actual = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); - TimTransmogrifier.updateRsuCreds(actual, rsuProperties); - - assertEquals(expected, actual); - } - - @Test - void testUpdateRsuCreds_UpdatedWhenEmptyString() { - RSU expected = new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(),1, 2000); - // rsuUsername and rsuPassword are blank - RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); - TimTransmogrifier.updateRsuCreds(actual3, rsuProperties); - assertEquals(expected, actual3); - } - - @Test - void testObfuscateRsuPassword() { - String actual = TimTransmogrifier.obfuscateRsuPassword( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); - assertEquals( - "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", - actual); - } - - void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) - throws JsonUtilsException, XmlUtilsException { - JsonNode obj = JsonUtils.toObjectNode(array); - JsonNode oldObj = obj.get(arrayKey); - - JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); - String actualXml = XmlUtils.toXmlStatic(newObj); - - assertEquals(expectedXml, actualXml); - } - - @Test - void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { - String single = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String singleXmlExpected = "127.0.0.3v3userpassword1100010"; - assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, singleXmlExpected); - - String multi = "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; - String multiXmlExpected = "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; - assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, multiXmlExpected); - } - - @Test - void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); - assertNull(actualASD); - } - - @Test - void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - inputServiceRequest.setSnmp(new SNMP()); - - assertThrows(TimTransmogrifierException.class, () -> TimTransmogrifier.buildASD(inputServiceRequest)); - } - - @Test - void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() { - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(new SDW()); - - assertThrows(TimTransmogrifierException.class, () -> TimTransmogrifier.buildASD(inputServiceRequest)); - } - - @Test - void testBuildASDValidTimeFromSNMP() - throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { - - SNMP inputSNMP = new SNMP(); - inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); - - SDW inputSDW = new SDW(); - inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setSnmp(inputSNMP); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - void testBuildASDValidTimeFromSDW() - throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - - assertNotNull(actualASD); - assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); - assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); - } - - @Test - void testConvertToXMLASD() - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, OdeGeoRegion.GeoRegionException { - - Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:00:15.190Z"), ZoneId.of("UTC")); - DateTimeUtils.setClock(fixedClock); - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, staticSerialId); - String expected = String.format("us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F000000001425379030-834779030423057530-8284275307876BA7F20320176117472018311747331", DateTimeUtils.now(), schemaVersion); - assertEquals(expected, actualXML); - } - - @Test - void testConvertToXMLMessageFrame() - throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, OdeGeoRegion.GeoRegionException { - - Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:36:15.170Z"), ZoneId.of("UTC")); - DateTimeUtils.setClock(fixedClock); - - SDW inputSDW = new SDW(); - inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); - inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); - inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); - - ServiceRequest inputServiceRequest = new ServiceRequest(); - inputServiceRequest.setSdw(inputSDW); - inputServiceRequest.setRsus(new RSU[0]); - - DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); - actualASD.setRequestID("7876BA7F"); - actualASD.getAsdmDetails().setAsdmID("7876BA7F"); - - TravelerInputData fakeTID = new TravelerInputData(); - fakeTID.setRequest(inputServiceRequest); - - ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); - - SerialId staticSerialId = new SerialId(); - staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); - - OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); - staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); - - String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); - var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", DateTimeUtils.now(), schemaVersion); - assertEquals(expected, actualXML); - } - - /** - * It should be noted that the 'prepare' section of this test largely follows the - * logic in the TimDepositController.depositTim() method. This is because the - * TimTransmogrifier.convertToXml() method is called by the TimDepositController - * and the TimDepositController is responsible for preparing the data that is - * passed to the TimTransmogrifier.convertToXml() method. - */ - @Test - void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() throws IOException, JsonUtilsException, XmlUtilsException, ParseException { - // prepare - String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); - - SerialId serialId = prepareSerialId(); - OdeTravelerInputData odeTID = prepareOdeTID(timRequestContainingCircleGeometry); - OdeRequestMsgMetadata timMetadata = prepareMetadata(odeTID, serialId); - - ObjectNode encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - - // Set the clock to a fixed instant for value comparison - DateTimeUtils.setClock(Clock.fixed(Instant.parse("2024-11-05T16:51:14.473Z"), ZoneId.of("UTC"))); - - // execute - String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); - - // verify - String expectedXml = new String(Files.readAllBytes(Paths.get("src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))) - .replaceAll("\\s", "") // remove all whitespace - .replaceAll("", ""); // add space before closing tag - Assertions.assertEquals(expectedXml, actualXML); - } - - @Test - void testCreateOdeTimData() throws JsonUtilsException { - - JSONObject testObject = JsonUtils - .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); - JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); - - assertEquals( - "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", - actualOdeTimData.toString()); - } - - @Test - void testConstructorIsPrivate() throws NoSuchMethodException { - - Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); - assertTrue(Modifier.isPrivate(constructor.getModifiers())); - constructor.setAccessible(true); - - assertThrows(InvocationTargetException.class, constructor::newInstance); - } - - /** - * Helper method to prepare a SerialId object for testing - * @return a SerialId object - */ - private SerialId prepareSerialId() { - SerialId serialId = new SerialId(); - serialId.setStreamId("testStreamId"); - return serialId; - } - - /** - * Helper method to prepare an OdeTravelerInputData object for testing - * @param timRequestContainingCircleGeometry a JSON string containing a TIM request with a circle geometry - * @return an OdeTravelerInputData object - * @throws JsonUtilsException if there is an issue parsing the JSON string - */ - private OdeTravelerInputData prepareOdeTID(String timRequestContainingCircleGeometry) throws JsonUtilsException { - return (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, OdeTravelerInputData.class, true); - } - - /** - * Helper method to prepare an OdeRequestMsgMetadata object for testing - * @param odeTID an OdeTravelerInputData object - * @param serialId a SerialId object - * @return an OdeRequestMsgMetadata object - * @throws ParseException if there is an issue parsing the date - */ - private OdeRequestMsgMetadata prepareMetadata(OdeTravelerInputData odeTID, SerialId serialId) throws ParseException { - ServiceRequest request = odeTID.getRequest(); - request.setOde(new ServiceRequest.OdeInternal()); - request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); - OdeTravelerInformationMessage tim = odeTID.getTim(); - OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); - OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); - timMetadata.setOdePacketID(tim.getPacketID()); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); - latestStartDateTime = latestStartDateTime == null || latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime; - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); - - timMetadata.setSerialId(serialId); - timMetadata.setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.TMC); - timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); - timMetadata.setSchemaVersion(7); - return timMetadata; + @Autowired + RsuProperties rsuProperties; + + private static final String schemaVersion = "7"; + + @Test + void testUpdateRsuCreds_UpdateWhenNull() { + RSU expected = + new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + + RSU actual = new RSU("127.0.0.1", null, null, 1, 2000); + TimTransmogrifier.updateRsuCreds(actual, rsuProperties); + + assertEquals(expected, actual); + } + + @Test + void testUpdateRsuCreds_DoNotOverwriteExisting() { + RSU expected = + new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + + RSU actual = + new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + TimTransmogrifier.updateRsuCreds(actual, rsuProperties); + + assertEquals(expected, actual); + } + + @Test + void testUpdateRsuCreds_UpdatedWhenEmptyString() { + RSU expected = + new RSU("127.0.0.1", rsuProperties.getUsername(), rsuProperties.getPassword(), 1, 2000); + // rsuUsername and rsuPassword are blank + RSU actual3 = new RSU("127.0.0.1", "", "", 1, 2000); + TimTransmogrifier.updateRsuCreds(actual3, rsuProperties); + assertEquals(expected, actual3); + } + + @Test + void testObfuscateRsuPassword() { + String actual = TimTransmogrifier.obfuscateRsuPassword( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\": \"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}"); + assertEquals( + "{\"metadata\":{\"request\":{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"sdw\":null,\"rsus\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"*\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeMsgPayload\",\"serialId\":{\"streamId\":\"59651ecc-240c-4440-9011-4a43c926817b\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2018-11-16T19:21:22.568Z\",\"schemaVersion\":6,\"recordGeneratedAt\":\"2017-03-13T06:07:11Z\",\"recordGeneratedBy\":\"TMC\",\"sanitized\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage\",\"data\":{\"msgCnt\":13,\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000000000000000\"},\"furtherInfoID\":null},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":22,\"priority\":0,\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":23,\"segmentID\":33,\"anchorPosition\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"laneWidth\":7,\"directionality\":3,\"closedPath\":false,\"direction\":\"1010101010101010\",\"description\":\"geometry\",\"path\":null,\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":1,\"laneWidth\":33,\"circle\":{\"position\":{\"latitude\":41.678473,\"longitude\":-108.782775,\"elevation\":917.1432},\"radius\":15,\"units\":7}},\"oldRegion\":null}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"Advisory\",\"items\":[\"125\",\"some text\",\"250\",\"\\u002798765\"],\"url\":\"null\"}],\"asnDataFrames\":null}}}", + actual); + } + + void assertConvertArray(String array, String arrayKey, String elementKey, Object expectedXml) + throws JsonUtilsException, XmlUtilsException { + JsonNode obj = JsonUtils.toObjectNode(array); + JsonNode oldObj = obj.get(arrayKey); + + JsonNode newObj = XmlUtils.createEmbeddedJsonArrayForXmlConversion(elementKey, oldObj); + String actualXml = XmlUtils.toXmlStatic(newObj); + + assertEquals(expectedXml, actualXml); + } + + @Test + void testConvertRsusArray() throws JsonUtilsException, XmlUtilsException { + String single = + "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String singleXmlExpected = + "127.0.0.3v3userpassword1100010"; + assertConvertArray(single, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, + singleXmlExpected); + + String multi = + "{\"ode\":{\"version\":3,\"verb\":\"POST\"},\"rsus\":{\"rsu_\":[{\"rsuTarget\":\"127.0.0.1\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":0,\"rsuTimeout\":2000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10},{\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":1,\"rsuTimeout\":1000,\"rsuIndex\":10}]},\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":31,\"mode\":1,\"channel\":178,\"interval\":2,\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":1,\"status\":4}}"; + String multiXmlExpected = + "127.0.0.1v3userpassword0200010127.0.0.2v3userpassword1100010127.0.0.3v3userpassword1100010"; + assertConvertArray(multi, TimTransmogrifier.RSUS_STRING, TimTransmogrifier.RSUS_STRING, + multiXmlExpected); + } + + @Test + void testBuildASDNoSDWReturnsNull() throws TimTransmogrifierException { + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(new ServiceRequest()); + assertNull(actualASD); + } + + @Test + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSNMP() { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + inputServiceRequest.setSnmp(new SNMP()); + + assertThrows(TimTransmogrifierException.class, + () -> TimTransmogrifier.buildASD(inputServiceRequest)); + } + + @Test + void testBuildASDNullTimeRethrowsTimeParsingExceptionFromSDW() { + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(new SDW()); + + assertThrows(TimTransmogrifierException.class, + () -> TimTransmogrifier.buildASD(inputServiceRequest)); + } + + @Test + void testBuildASDValidTimeFromSNMP() + throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { + + SNMP inputSNMP = new SNMP(); + inputSNMP.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSNMP.setDeliverystop("2018-03-01T17:47:11-05:15"); + + SDW inputSDW = new SDW(); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setSnmp(inputSNMP); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + void testBuildASDValidTimeFromSDW() + throws TimTransmogrifierException, OdeGeoRegion.GeoRegionException { + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + + assertNotNull(actualASD); + assertEquals(Integer.valueOf(6), actualASD.getAsdmDetails().getStartTime().getMonth()); + assertEquals(Integer.valueOf(3), actualASD.getAsdmDetails().getStopTime().getMonth()); + } + + @Test + void testConvertToXMLASD() + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, + OdeGeoRegion.GeoRegionException { + + Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:00:15.190Z"), ZoneId.of("UTC")); + DateTimeUtils.setClock(fixedClock); + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = TimTransmogrifier.convertToXml(actualASD, encodableTID, staticOdeMsgMetadata, + staticSerialId); + String expected = String.format( + "us.dot.its.jpo.ode.model.OdeAsdPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERIeee1609Dot2DataIeee1609Dot2DataCOERAdvisorySituationDataAdvisorySituationDataUPERus.dot.its.jpo.ode.plugin.j2735.DdsAdvisorySituationData1565000000007876BA7F000000001425379030-834779030423057530-8284275307876BA7F20320176117472018311747331", + DateTimeUtils.now(), schemaVersion); + assertEquals(expected, actualXML); + } + + @Test + void testConvertToXMLMessageFrame() + throws TimTransmogrifierException, JsonUtilsException, XmlUtilsException, + OdeGeoRegion.GeoRegionException { + + Clock fixedClock = Clock.fixed(Instant.parse("2024-10-30T19:36:15.170Z"), ZoneId.of("UTC")); + DateTimeUtils.setClock(fixedClock); + + SDW inputSDW = new SDW(); + inputSDW.setDeliverystart("2017-06-01T17:47:11-05:00"); + inputSDW.setDeliverystop("2018-03-01T17:47:11-05:15"); + inputSDW.setServiceRegion(new OdeGeoRegion("42.537903,-83.477903 42.305753, -82.842753")); + + ServiceRequest inputServiceRequest = new ServiceRequest(); + inputServiceRequest.setSdw(inputSDW); + inputServiceRequest.setRsus(new RSU[0]); + + DdsAdvisorySituationData actualASD = TimTransmogrifier.buildASD(inputServiceRequest); + actualASD.setRequestID("7876BA7F"); + actualASD.getAsdmDetails().setAsdmID("7876BA7F"); + + TravelerInputData fakeTID = new TravelerInputData(); + fakeTID.setRequest(inputServiceRequest); + + ObjectNode encodableTID = JsonUtils.toObjectNode(JsonUtils.toJson(fakeTID, false)); + + SerialId staticSerialId = new SerialId(); + staticSerialId.setStreamId("6c33f802-418d-4b67-89d1-326b4fc8b1e3"); + + OdeMsgMetadata staticOdeMsgMetadata = new OdeMsgMetadata(); + staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); + + String actualXML = + TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); + var expected = String.format( + "us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", + DateTimeUtils.now(), schemaVersion); + assertEquals(expected, actualXML); + } + + /** + * It should be noted that the 'prepare' section of this test largely follows the + * logic in the TimDepositController.depositTim() method. This is because the + * TimTransmogrifier.convertToXml() method is called by the TimDepositController + * and the TimDepositController is responsible for preparing the data that is + * passed to the TimTransmogrifier.convertToXml() method. + */ + @Test + void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() + throws IOException, JsonUtilsException, XmlUtilsException, ParseException { + // prepare + String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); + + SerialId serialId = prepareSerialId(); + OdeTravelerInputData odeTID = prepareOdeTID(timRequestContainingCircleGeometry); + OdeRequestMsgMetadata timMetadata = prepareMetadata(odeTID, serialId); + + ObjectNode encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); + + // Set the clock to a fixed instant for value comparison + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-05T16:51:14.473Z"), ZoneId.of("UTC"))); + + // execute + String actualXML = TimTransmogrifier.convertToXml(null, encodableTid, timMetadata, serialId); + + // verify + String expectedXml = new String(Files.readAllBytes(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))) + .replaceAll("\\s", "") // remove all whitespace + .replaceAll("", ""); // add space before closing tag + Assertions.assertEquals(expectedXml, actualXML); + } + + @Test + void testCreateOdeTimData() throws JsonUtilsException { + + JSONObject testObject = JsonUtils + .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); + JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); + + assertEquals( + "{\"metadata\":{\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"object\":\"value\"},\"payload\":{\"dataType\":\"TravelerInformation\",\"object\":\"value\"}}", + actualOdeTimData.toString()); + } + + @Test + void testConstructorIsPrivate() throws NoSuchMethodException { + + Constructor constructor = TimTransmogrifier.class.getDeclaredConstructor(); + assertTrue(Modifier.isPrivate(constructor.getModifiers())); + constructor.setAccessible(true); + + assertThrows(InvocationTargetException.class, constructor::newInstance); + } + + /** + * Helper method to prepare a SerialId object for testing + * + * @return a SerialId object + */ + private SerialId prepareSerialId() { + SerialId serialId = new SerialId(); + serialId.setStreamId("testStreamId"); + return serialId; + } + + /** + * Helper method to prepare an OdeTravelerInputData object for testing + * + * @param timRequestContainingCircleGeometry a JSON string containing a TIM request with a circle geometry + * @return an OdeTravelerInputData object + * @throws JsonUtilsException if there is an issue parsing the JSON string + */ + private OdeTravelerInputData prepareOdeTID(String timRequestContainingCircleGeometry) + throws JsonUtilsException { + return (OdeTravelerInputData) JsonUtils.jacksonFromJson(timRequestContainingCircleGeometry, + OdeTravelerInputData.class, true); + } + + /** + * Helper method to prepare an OdeRequestMsgMetadata object for testing + * + * @param odeTID an OdeTravelerInputData object + * @param serialId a SerialId object + * @return an OdeRequestMsgMetadata object + * @throws ParseException if there is an issue parsing the date + */ + private OdeRequestMsgMetadata prepareMetadata(OdeTravelerInputData odeTID, SerialId serialId) + throws ParseException { + ServiceRequest request = odeTID.getRequest(); + request.setOde(new ServiceRequest.OdeInternal()); + request.getOde().setVerb(ServiceRequest.OdeInternal.RequestVerb.PUT); + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + timMetadata.setOdePacketID(tim.getPacketID()); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); + latestStartDateTime = latestStartDateTime == null || + latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime; } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + + timMetadata.setSerialId(serialId); + timMetadata.setRecordGeneratedBy(OdeMsgMetadata.GeneratedBy.TMC); + timMetadata.setRecordGeneratedAt( + DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + timMetadata.setSchemaVersion(7); + return timMetadata; + } } From e5f447fde268947dda9200f0260226541d6ad9c4 Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Tue, 3 Dec 2024 09:27:59 -0700 Subject: [PATCH 110/264] add missing confluent.password and confluent.username to application.yaml --- jpo-ode-svcs/src/main/resources/application.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index ed75da618..b0b622de9 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -32,6 +32,9 @@ ode: kafka: brokers: ${DOCKER_HOST_IP}:9092 kafka-type: ${KAFKA_TYPE} + confluent: + password: ${CONFLUENT_SECRET} + username: ${CONFLUENT_KEY} producer: type: "sync" acks: ${KAFKA_ACKS} From b094a6cbf6e942ab74faec696cacce2e4431e2cf Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Tue, 3 Dec 2024 10:02:43 -0700 Subject: [PATCH 111/264] swap ODE_KAFKA_BROKERS in for DOCKER_HOST_IP for kafka configs. update sample.env --- jpo-ode-svcs/src/main/resources/application.yaml | 6 +++--- sample.env | 5 +++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index b0b622de9..c9d4bb393 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -5,14 +5,14 @@ spring: consumer: enable-auto-commit: true auto-commit-interval: 1000 - bootstrap-servers: ${DOCKER_HOST_IP}:9092 + bootstrap-servers: ${ODE_KAFKA_BROKERS}:9092 producer: acks: "all" retries: 0 batch-size: 16384 compression-type: "zstd" buffer-memory: 33554432 - bootstrap-servers: ${DOCKER_HOST_IP}:9092 + bootstrap-servers: ${ODE_KAFKA_BROKERS}:9092 http: multipart: max-file-size: 1MB @@ -30,7 +30,7 @@ ode: username: ${RSU_USERNAME} password: ${RSU_PASSWORD} kafka: - brokers: ${DOCKER_HOST_IP}:9092 + brokers: ${ODE_KAFKA_BROKERS}:9092 kafka-type: ${KAFKA_TYPE} confluent: password: ${CONFLUENT_SECRET} diff --git a/sample.env b/sample.env index 5e7bfa46a..78bfe75b3 100644 --- a/sample.env +++ b/sample.env @@ -19,6 +19,11 @@ # Hint: look for "inet addr:" within "eth0" or "en0" for OSX DOCKER_HOST_IP= +# (Required) Locally, this is the IP address of Docker host machine which can be found by running "ip -4 addr" +# In cloud deployments, this variable is set automatically via https://github.com/usdot-jpo-ode/jpo-ode/blob/1281a4901db32659ba75e5123f6c5f5fa6371156/docs/k8s-demo/templates/jpoode_ode.yaml#L142 +# Hint: look for "inet addr:" within "eth0" or "en0" for OSX +ODE_KAFKA_BROKERS= + # (Required) The full path of a directory on the host machine to be shared with docker containers. # Hint: usually the path to the `jpo-ode` directory. DOCKER_SHARED_VOLUME= From 270e5bb3e55946790d810d170567a870ad77aa90 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:30:31 -0700 Subject: [PATCH 112/264] fixing confluent authentication properties and updating environmental variable references --- docker-compose.yml | 1 + .../us/dot/its/jpo/ode/wrapper/MessageConsumer.java | 1 + .../us/dot/its/jpo/ode/wrapper/MessageProducer.java | 1 + .../us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java | 6 ++++++ .../us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java | 6 ++++++ jpo-ode-svcs/src/main/resources/application.yaml | 10 +++++----- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 480e62885..b5172e1dc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,6 +32,7 @@ services: - "6666:6666/udp" environment: DOCKER_HOST_IP: ${DOCKER_HOST_IP} + ODE_KAFKA_BROKERS: ${DOCKER_HOST_IP}:9092 ODE_SECURITY_SVCS_SIGNATURE_URI: ${ODE_SECURITY_SVCS_SIGNATURE_URI} ODE_RSU_USERNAME: ${ODE_RSU_USERNAME} ODE_RSU_PASSWORD: ${ODE_RSU_PASSWORD} diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageConsumer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageConsumer.java index 2e952a269..5ddadd9bd 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageConsumer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageConsumer.java @@ -120,6 +120,7 @@ public MessageConsumer( } private Properties addConfluentProperties(Properties props) { + logger.info("Adding Confluent properties"); props.put("ssl.endpoint.identification.algorithm", "https"); props.put("security.protocol", "SASL_SSL"); props.put("sasl.mechanism", "PLAIN"); diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java index 824b4e247..3e114b728 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/MessageProducer.java @@ -153,6 +153,7 @@ private Properties setDefaultProperties() { } private void addConfluentProperties(Properties props) { + log.info("Adding Confluent properties"); props.put("ssl.endpoint.identification.algorithm", "https"); props.put("security.protocol", "SASL_SSL"); props.put("sasl.mechanism", "PLAIN"); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java index 57ce997c6..e5926f8f3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java @@ -38,6 +38,9 @@ public KafkaConsumerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties o public ConsumerFactory consumerFactory() { var consumerProps = kafkaProperties.buildConsumerProperties(); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + consumerProps.put("ssl.endpoint.identification.algorithm", "https"); + consumerProps.put("security.protocol", "SASL_SSL"); + consumerProps.put("sasl.mechanism", "PLAIN"); consumerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); } return new DefaultKafkaConsumerFactory<>(consumerProps); @@ -54,6 +57,9 @@ public ConcurrentKafkaListenerContainerFactory kafkaListenerCont public ConsumerFactory odeMapDataConsumerFactory() { Map props = new HashMap<>(kafkaProperties.buildConsumerProperties()); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + props.put("ssl.endpoint.identification.algorithm", "https"); + props.put("security.protocol", "SASL_SSL"); + props.put("sasl.mechanism", "PLAIN"); props.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); } return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(OdeMapData.class)); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java index 649a6f585..ecfebe91a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java @@ -26,6 +26,9 @@ public KafkaProducerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties o public ProducerFactory producerFactory() { var producerProps = kafkaProperties.buildProducerProperties(); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + producerProps.put("ssl.endpoint.identification.algorithm", "https"); + producerProps.put("security.protocol", "SASL_SSL"); + producerProps.put("sasl.mechanism", "PLAIN"); producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); } return new DefaultKafkaProducerFactory<>(producerProps); @@ -40,6 +43,9 @@ public KafkaTemplate kafkaTemplate() { public ProducerFactory odeDataProducerFactory() { var producerProps = kafkaProperties.buildProducerProperties(); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + producerProps.put("ssl.endpoint.identification.algorithm", "https"); + producerProps.put("security.protocol", "SASL_SSL"); + producerProps.put("sasl.mechanism", "PLAIN"); producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); } return new DefaultKafkaProducerFactory<>(producerProps, diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index b0b622de9..da87eeae7 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -5,14 +5,14 @@ spring: consumer: enable-auto-commit: true auto-commit-interval: 1000 - bootstrap-servers: ${DOCKER_HOST_IP}:9092 + bootstrap-servers: ${ODE_KAFKA_BROKERS} producer: acks: "all" retries: 0 batch-size: 16384 compression-type: "zstd" buffer-memory: 33554432 - bootstrap-servers: ${DOCKER_HOST_IP}:9092 + bootstrap-servers: ${ODE_KAFKA_BROKERS} http: multipart: max-file-size: 1MB @@ -27,10 +27,10 @@ ode: is-sdw-signing-enabled: ${DATA_SIGNING_ENABLED_SDW} rsu: srm-slots: 100 - username: ${RSU_USERNAME} - password: ${RSU_PASSWORD} + username: ${ODE_RSU_USERNAME} + password: ${ODE_RSU_PASSWORD} kafka: - brokers: ${DOCKER_HOST_IP}:9092 + brokers: ${ODE_KAFKA_BROKERS} kafka-type: ${KAFKA_TYPE} confluent: password: ${CONFLUENT_SECRET} From 5c1892e80edf81fd11f90212f42e9e5cc6945a09 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 13:04:07 -0700 Subject: [PATCH 113/264] Add @JsonIgnore to fields on asn1 type base classes --- .../us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java | 8 ++++++++ .../java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java | 2 ++ .../java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java | 5 +++++ .../us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java | 3 +++ 4 files changed, 18 insertions(+) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java index d7328bfcc..b1750cfd7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonIgnore; import us.dot.its.jpo.ode.plugin.serialization.BitstringSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -11,9 +12,16 @@ @JsonSerialize(using = BitstringSerializer.class) public abstract class Asn1Bitstring implements Asn1Type { + @JsonIgnore final BitSet bits; + + @JsonIgnore final int size; + + @JsonIgnore final boolean hasExtensionMarker; + + @JsonIgnore final String[] names; public Asn1Bitstring(int size, boolean hasExtensionMarker, String[] names) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java index edb753de9..a6ba3e5b3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonIgnore; import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -9,6 +10,7 @@ public abstract class Asn1Choice implements Asn1Type { + @JsonIgnore final boolean hasExtensionMarker; public Asn1Choice(boolean hasExtensionMarker) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java index 7dc62b002..c3ef31ccb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonValue; import java.util.Objects; @@ -12,7 +13,11 @@ public class Asn1Integer implements Asn1Type, Comparable { protected long value; + + @JsonIgnore final long lowerBound; + + @JsonIgnore final long upperBound; public Asn1Integer(long lowerBound, long upperBound) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java index 9a81fceda..d3d792d41 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java @@ -1,17 +1,20 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonIgnore; import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class Asn1Sequence implements Asn1Type { + @JsonIgnore final boolean extensionMarker; public Asn1Sequence(boolean hasExtensionMarker) { this.extensionMarker = hasExtensionMarker; } + @JsonIgnore public boolean hasExtensionMarker() { return extensionMarker; } From f4a85e64fd23134dd02e9e058f0a569bb2e41a73 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 16:42:25 -0700 Subject: [PATCH 114/264] Serialize Bitstrings as verbose maps for ODE JSON --- .../plugin/serialization/BitstringSerializer.java | 13 ++++++++++--- .../dot/its/jpo/ode/plugin/types/Asn1Bitstring.java | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java index 1f4616964..689699af3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java @@ -7,6 +7,7 @@ import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; import java.io.IOException; +import java.util.LinkedHashMap; /** * Serializer for ASN.1 Bitstring types to XER or JER @@ -21,11 +22,17 @@ protected BitstringSerializer() { @Override public void serialize(Asn1Bitstring asn1Bitstring, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { if (serializerProvider instanceof XmlSerializerProvider) { - // XER serializes enums as binary + // XER serializes bitstrings as binary strings jsonGenerator.writeString(asn1Bitstring.binaryString()); } else { - // JER serializes enums as hex - jsonGenerator.writeString(asn1Bitstring.hexString()); + // ODE JSON dialect serializes bitstrings as verbose maps + jsonGenerator.writeStartObject(); + for (int i = 0; i < asn1Bitstring.size(); i++) { + String name = asn1Bitstring.name(i); + boolean isSet = asn1Bitstring.get(i); + jsonGenerator.writeBooleanField(name, isSet); + } + jsonGenerator.writeEndObject(); } } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java index b1750cfd7..1f4029d5b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -6,6 +6,8 @@ import java.util.BitSet; import java.util.HexFormat; +import java.util.LinkedHashMap; +import java.util.Map; import static us.dot.its.jpo.ode.plugin.utils.BitUtils.reverseBits; From 3603e0f41956f5a98fda41abdabf54d96429a4b6 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:07:21 -0700 Subject: [PATCH 115/264] Set extension presence booleans to jsonignore annotations --- .../us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java | 9 +++++++++ .../java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java | 3 +++ .../us/dot/its/jpo/ode/plugin/types/Asn1Integer.java | 5 +++++ .../us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java | 4 ++++ 4 files changed, 21 insertions(+) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java index d7328bfcc..002a25a1b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.types; import us.dot.its.jpo.ode.plugin.serialization.BitstringSerializer; + +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.util.BitSet; @@ -11,9 +13,16 @@ @JsonSerialize(using = BitstringSerializer.class) public abstract class Asn1Bitstring implements Asn1Type { + @JsonIgnore final BitSet bits; + + @JsonIgnore final int size; + + @JsonIgnore final boolean hasExtensionMarker; + + @JsonIgnore final String[] names; public Asn1Bitstring(int size, boolean hasExtensionMarker, String[] names) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java index edb753de9..5f1cd293c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.types; import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; + +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -9,6 +11,7 @@ public abstract class Asn1Choice implements Asn1Type { + @JsonIgnore final boolean hasExtensionMarker; public Asn1Choice(boolean hasExtensionMarker) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java index 7dc62b002..c3ef31ccb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonValue; import java.util.Objects; @@ -12,7 +13,11 @@ public class Asn1Integer implements Asn1Type, Comparable { protected long value; + + @JsonIgnore final long lowerBound; + + @JsonIgnore final long upperBound; public Asn1Integer(long lowerBound, long upperBound) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java index 9a81fceda..ec4b2eebe 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java @@ -1,17 +1,21 @@ package us.dot.its.jpo.ode.plugin.types; import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; + +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public abstract class Asn1Sequence implements Asn1Type { + @JsonIgnore final boolean extensionMarker; public Asn1Sequence(boolean hasExtensionMarker) { this.extensionMarker = hasExtensionMarker; } + @JsonIgnore public boolean hasExtensionMarker() { return extensionMarker; } From 7c991f5f4a0a52ecc1b6149734bad3d83661076f Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:09:24 -0700 Subject: [PATCH 116/264] BitString serialization rules to build them out as verbose boolean sequences --- .../plugin/serialization/BitstringSerializer.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java index 1f4616964..a4aaf2e1d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java @@ -21,11 +21,17 @@ protected BitstringSerializer() { @Override public void serialize(Asn1Bitstring asn1Bitstring, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { if (serializerProvider instanceof XmlSerializerProvider) { - // XER serializes enums as binary + // XER serializes bitstrings as binary strings jsonGenerator.writeString(asn1Bitstring.binaryString()); } else { - // JER serializes enums as hex - jsonGenerator.writeString(asn1Bitstring.hexString()); + // ODE JSON dialect serializes bitstrings as verbose maps + jsonGenerator.writeStartObject(); + for (int i = 0; i < asn1Bitstring.size(); i++) { + String name = asn1Bitstring.name(i); + boolean isSet = asn1Bitstring.get(i); + jsonGenerator.writeBooleanField(name, isSet); + } + jsonGenerator.writeEndObject(); } } } From c5e7bda92fc8de28e8d65c1acb69e7fc3acdba12 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:16:17 -0700 Subject: [PATCH 117/264] Bitstring deserializer for verbose ODE json --- .../serialization/BitStringDeserializer.java | 16 ++++++-- .../serialization/BitstringSerializer.java | 1 + .../jpo/ode/plugin/types/Asn1Bitstring.java | 10 +++++ .../plugin/j2735/DSRC/HeadingSliceTest.java | 37 +++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java index b7aeeb0e1..b90f4fee0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.plugin.serialization; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.core.type.TypeReference; import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; @@ -8,9 +10,11 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper; import java.io.IOException; +import java.util.Map; /** - * Deserialize an ASN.1 Bitstring from XER or JER + * Deserialize an ASN.1 Bitstring from XER or JER. + *

Note that this deserializer expects ODE JSON, not standard JER. * @param The bitstring type * @author Ivan Yourshaw */ @@ -24,14 +28,18 @@ protected BitStringDeserializer(Class valueClass) { @Override public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - String str = jsonParser.getText(); T bitstring = construct(); if (jsonParser.getCodec() instanceof XmlMapper) { // XML: binary + String str = jsonParser.getText(); bitstring.fromBinaryString(str); } else { - // JSON: hex - bitstring.fromHexString(str); + // ODE JSON dialect: read verbose map + TypeReference> boolMapType = new TypeReference<>() {}; + Map map = jsonParser.readValueAs(boolMapType); + for (var keyValue : map.entrySet()) { + bitstring.set(keyValue.getKey(), keyValue.getValue()); + } } return bitstring; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java index 689699af3..122cb1fa2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java @@ -11,6 +11,7 @@ /** * Serializer for ASN.1 Bitstring types to XER or JER + *

Note that this serializer writes ODE JSON, not standard JER. * @author Ivan Yourshaw */ public class BitstringSerializer extends StdSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java index 1f4029d5b..e66b96570 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -49,6 +49,16 @@ public void set(int bitIndex, boolean value) { bits.set(bitIndex, value); } + public void set(String name, boolean value) { + for (int i = 0; i < size; i++) { + if (name(i).equals(name)) { + set(i, value); + return; + } + } + throw new IllegalArgumentException("Unknown name " + name); + } + public String binaryString() { char[] chars = new char[size]; for (int i = 0; i < size; i++) { diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java new file mode 100644 index 000000000..47e4c1405 --- /dev/null +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java @@ -0,0 +1,37 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test serializing and deserializing a HeadingSlice bitstring to ODE JSON. + */ +public class HeadingSliceTest { + + private final static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void testDeserializeJson() throws JsonProcessingException { + HeadingSlice hs = mapper.readValue(EXPECTED_JSON, HeadingSlice.class); + assertNotNull(hs); + for (int i = 0; i < hs.size(); i++) { + assertTrue(hs.get(i)); + } + } + + @Test + public void testSerializeJson() throws JsonProcessingException { + var hs = new HeadingSlice(); + for (int i = 0; i < hs.size(); i++) { + hs.set(i, true); + } + String json = mapper.writeValueAsString(hs); + assertEquals(EXPECTED_JSON, json); + } + + private final static String EXPECTED_JSON = """ + {"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true,"from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true,"from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true,"from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true,"from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true,"from337-5to360-0degrees":true}"""; +} From 578e2ccb48eb39e44682bd10441395cc9e5ccf6d Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:35:44 -0700 Subject: [PATCH 118/264] Remove diagnostic logging statements --- .../its/jpo/ode/plugin/serialization/IntegerDeserializer.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java index 4e044314a..5ccf5f343 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java @@ -28,9 +28,6 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati if (jsonParser instanceof FromXmlParser xmlParser) { result = construct(); TreeNode node = xmlParser.getCodec().readTree(xmlParser); - System.out.printf("type: %s%n", thisClass.getName()); - System.out.printf("node: %s%n", node); - System.out.printf("node type: %s%n", node.getClass().getName()); if (node instanceof NumericNode numNode) { result.setValue(numNode.longValue()); } else if (node instanceof TextNode textNode) { From 651941e698dced8ef136c20bd79f7ad9b5cf1fcc Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 18:37:41 -0700 Subject: [PATCH 119/264] Remove printf statements --- .../serialization/SequenceOfEnumeratedDeserializer.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java index e99b69f28..6b69eb5f8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java @@ -33,12 +33,11 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati // Unwrapped enum items result = construct(); TreeNode node = xmlParser.getCodec().readTree(xmlParser); - System.out.printf("type: %s%n", thisClass.getName()); - System.out.printf("node: %s%n", node); + var fieldNameIterator = node.fieldNames(); while (fieldNameIterator.hasNext()) { String name = fieldNameIterator.next(); - System.out.printf("enum value: %s%n", name); + for (S enumValue : listEnumValues()) { if (Objects.equals(enumValue.getName(), name)) { result.add(enumValue); From afee4837c393d185d812d99d44866544b21d8234 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:04:19 -0700 Subject: [PATCH 120/264] Set tim udp buffer size to 2048. Add complex tim example to script --- jpo-ode-svcs/src/main/resources/application.yaml | 2 +- scripts/tests/udpsender_tim.py | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/jpo-ode-svcs/src/main/resources/application.yaml b/jpo-ode-svcs/src/main/resources/application.yaml index f6418668d..410d5279b 100644 --- a/jpo-ode-svcs/src/main/resources/application.yaml +++ b/jpo-ode-svcs/src/main/resources/application.yaml @@ -107,7 +107,7 @@ ode: buffer-size: 500 receiver-port: 44900 tim: - buffer-size: 500 + buffer-size: 2048 receiver-port: 47900 file-importer: buffer-size: 500 diff --git a/scripts/tests/udpsender_tim.py b/scripts/tests/udpsender_tim.py index afc542385..1f6dbd260 100644 --- a/scripts/tests/udpsender_tim.py +++ b/scripts/tests/udpsender_tim.py @@ -5,7 +5,8 @@ # Currently set to oim-dev environment's ODE UDP_IP = os.getenv('DOCKER_HOST_IP') UDP_PORT = 47900 -MESSAGE = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e" +#MESSAGE = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e" +MESSAGE = "001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240" print("UDP target IP:", UDP_IP) print("UDP target port:", UDP_PORT) From 235f51a6bbfe2d3418e0361eae5c9b72cf3c3111 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Tue, 3 Dec 2024 19:13:10 -0700 Subject: [PATCH 121/264] Complex example tims --- scripts/tests/udpsender_tim.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/scripts/tests/udpsender_tim.py b/scripts/tests/udpsender_tim.py index 1f6dbd260..3638e8317 100644 --- a/scripts/tests/udpsender_tim.py +++ b/scripts/tests/udpsender_tim.py @@ -5,8 +5,15 @@ # Currently set to oim-dev environment's ODE UDP_IP = os.getenv('DOCKER_HOST_IP') UDP_PORT = 47900 + +# Normal TIM message #MESSAGE = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e" -MESSAGE = "001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240" + +# Complex random example (with computed lanes) +#MESSAGE = "001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240" + +# Complex random example +MESSAGE = "001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A6" print("UDP target IP:", UDP_IP) print("UDP target port:", UDP_PORT) From ef385c602e48b160b2e047fe37b7f1de19fdbcdc Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:59:15 -0700 Subject: [PATCH 122/264] Comment manual edits --- .../us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java | 2 +- .../dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java index fc868e168..cfe03e8ef 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java @@ -17,7 +17,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; /** - * + * EDITED: Fixed "notUsed" properties. *

* This source code was generated by a tool. Manual edits are futile. *

diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java index f83b11b43..804a14f63 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java @@ -13,7 +13,7 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; /** - * + * EDITED: Changed base class to Asn1Object. *

* This source code was generated by a tool. Manual edits are futile. *

From 2568fab8429da5c0178ddb8e9b15a4271c6ddb3e Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:20:24 -0700 Subject: [PATCH 123/264] Java style: use Lobok for getters/setters, capitalize enum items --- jpo-ode-plugins/pom.xml | 3 + .../ode/plugin/annotations/package-info.java | 2 +- .../ode/plugin/j2735/AddGrpB/DegreesLat.java | 31 +- .../ode/plugin/j2735/AddGrpB/DegreesLong.java | 31 +- .../ode/plugin/j2735/AddGrpB/Elevation.java | 31 +- .../AddGrpB/LaneDataAttribute_addGrpB.java | 31 +- ...ttribute_addGrpBReg_LaneDataAttribute.java | 31 +- ...eg_LaneDataAttributeValueDeserializer.java | 31 +- ...BReg_LaneDataAttributeValueSerializer.java | 31 +- .../ode/plugin/j2735/AddGrpB/LatitudeDMS.java | 31 +- .../plugin/j2735/AddGrpB/LatitudeDMS2.java | 59 ++- .../plugin/j2735/AddGrpB/LongitudeDMS.java | 31 +- .../plugin/j2735/AddGrpB/LongitudeDMS2.java | 59 ++- .../plugin/j2735/AddGrpB/MinutesAngle.java | 31 +- .../AddGrpB/NodeOffsetPointXY_addGrpB.java | 51 ++- ...tPointXY_addGrpBReg_NodeOffsetPointXY.java | 31 +- ...eg_NodeOffsetPointXYValueDeserializer.java | 31 +- ...BReg_NodeOffsetPointXYValueSerializer.java | 31 +- .../plugin/j2735/AddGrpB/Node_LLdms_48b.java | 51 ++- .../plugin/j2735/AddGrpB/Node_LLdms_80b.java | 51 ++- .../j2735/AddGrpB/Position3D_addGrpB.java | 59 ++- .../Position3D_addGrpBReg_Position3D.java | 31 +- ...ddGrpBReg_Position3DValueDeserializer.java | 31 +- ..._addGrpBReg_Position3DValueSerializer.java | 31 +- .../plugin/j2735/AddGrpB/SecondsAngle.java | 31 +- .../ode/plugin/j2735/AddGrpC/Altitude.java | 51 ++- .../j2735/AddGrpC/AltitudeConfidence.java | 53 +-- .../AltitudeConfidenceDeserializer.java | 31 +- .../AddGrpC/AltitudeConfidenceSerializer.java | 31 +- .../plugin/j2735/AddGrpC/AltitudeValue.java | 31 +- .../j2735/AddGrpC/Position3D_addGrpC.java | 43 ++- .../Position3D_addGrpCReg_Position3D.java | 31 +- ...ddGrpCReg_Position3DValueDeserializer.java | 31 +- ..._addGrpCReg_Position3DValueSerializer.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/Angle.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/Circle.java | 59 ++- .../ode/plugin/j2735/DSRC/ComputedLane.java | 129 ++----- .../its/jpo/ode/plugin/j2735/DSRC/DYear.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/DeltaAngle.java | 31 +- .../plugin/j2735/DSRC/DescriptiveName.java | 31 +- .../ode/plugin/j2735/DSRC/DirectionOfUse.java | 43 +-- .../DSRC/DirectionOfUseDeserializer.java | 31 +- .../j2735/DSRC/DirectionOfUseSerializer.java | 31 +- .../ode/plugin/j2735/DSRC/DistanceUnits.java | 45 +-- .../j2735/DSRC/DistanceUnitsDeserializer.java | 31 +- .../j2735/DSRC/DistanceUnitsSerializer.java | 31 +- .../plugin/j2735/DSRC/DrivenLineOffsetLg.java | 31 +- .../plugin/j2735/DSRC/DrivenLineOffsetSm.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Elevation.java | 31 +- .../ode/plugin/j2735/DSRC/ExitService.java | 31 +- .../j2735/DSRC/ExitServiceSequence.java | 61 ++- .../its/jpo/ode/plugin/j2735/DSRC/Extent.java | 61 +-- .../plugin/j2735/DSRC/ExtentDeserializer.java | 31 +- .../plugin/j2735/DSRC/ExtentSerializer.java | 31 +- .../ode/plugin/j2735/DSRC/FurtherInfoID.java | 31 +- .../ode/plugin/j2735/DSRC/GenericSignage.java | 31 +- .../j2735/DSRC/GenericSignageSequence.java | 61 ++- .../plugin/j2735/DSRC/GeographicalPath.java | 135 ++----- .../j2735/DSRC/GeometricProjection.java | 77 ++-- .../ode/plugin/j2735/DSRC/HeadingSlice.java | 31 +- .../j2735/DSRC/HeadingSliceDeserializer.java | 31 +- .../ode/plugin/j2735/DSRC/ITIStextPhrase.java | 31 +- .../plugin/j2735/DSRC/LaneDataAttribute.java | 93 ++--- .../j2735/DSRC/LaneDataAttributeList.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/LaneID.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/LaneWidth.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Latitude.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Longitude.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/MUTCDCode.java | 45 +-- .../j2735/DSRC/MUTCDCodeDeserializer.java | 31 +- .../j2735/DSRC/MUTCDCodeSerializer.java | 31 +- .../j2735/DSRC/MergeDivergeNodeAngle.java | 31 +- .../plugin/j2735/DSRC/MinuteOfTheYear.java | 31 +- .../plugin/j2735/DSRC/MinutesDuration.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/MsgCount.java | 31 +- .../plugin/j2735/DSRC/NodeAttributeLL.java | 51 +-- .../DSRC/NodeAttributeLLDeserializer.java | 31 +- .../j2735/DSRC/NodeAttributeLLList.java | 31 +- .../j2735/DSRC/NodeAttributeLLSerializer.java | 31 +- .../plugin/j2735/DSRC/NodeAttributeSetLL.java | 93 ++--- .../plugin/j2735/DSRC/NodeAttributeSetXY.java | 93 ++--- .../plugin/j2735/DSRC/NodeAttributeXY.java | 51 +-- .../DSRC/NodeAttributeXYDeserializer.java | 31 +- .../j2735/DSRC/NodeAttributeXYList.java | 31 +- .../j2735/DSRC/NodeAttributeXYSerializer.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/NodeLL.java | 51 ++- .../jpo/ode/plugin/j2735/DSRC/NodeListLL.java | 43 ++- .../jpo/ode/plugin/j2735/DSRC/NodeListXY.java | 51 ++- .../plugin/j2735/DSRC/NodeOffsetPointLL.java | 99 ++--- .../plugin/j2735/DSRC/NodeOffsetPointXY.java | 99 ++--- .../jpo/ode/plugin/j2735/DSRC/NodeSetLL.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/NodeSetXY.java | 31 +- .../its/jpo/ode/plugin/j2735/DSRC/NodeXY.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_24B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_28B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_32B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_36B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_44B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LL_48B.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_LLmD_64b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_20b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_22b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_24b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_26b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_28b.java | 51 ++- .../ode/plugin/j2735/DSRC/Node_XY_32b.java | 51 ++- .../ode/plugin/j2735/DSRC/OffsetLL_B12.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetLL_B14.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetLL_B16.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetLL_B18.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetLL_B22.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetLL_B24.java | 31 +- .../ode/plugin/j2735/DSRC/OffsetSystem.java | 69 ++-- .../jpo/ode/plugin/j2735/DSRC/Offset_B10.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Offset_B11.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Offset_B12.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Offset_B13.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Offset_B14.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Offset_B16.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Position3D.java | 69 ++-- .../jpo/ode/plugin/j2735/DSRC/Radius_B12.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/RegionId.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/RegionList.java | 31 +- .../ode/plugin/j2735/DSRC/RegionOffsets.java | 59 ++- .../ode/plugin/j2735/DSRC/RegionPointSet.java | 59 ++- .../plugin/j2735/DSRC/RegionalExtension.java | 31 +- .../j2735/DSRC/RegulatorySpeedLimit.java | 51 ++- .../plugin/j2735/DSRC/RoadRegulatorID.java | 31 +- .../ode/plugin/j2735/DSRC/RoadSegmentID.java | 31 +- .../j2735/DSRC/RoadSegmentReferenceID.java | 51 ++- .../jpo/ode/plugin/j2735/DSRC/RoadSignID.java | 67 ++-- .../plugin/j2735/DSRC/RoadwayCrownAngle.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/SSPindex.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/Scale_B12.java | 31 +- .../plugin/j2735/DSRC/SegmentAttributeLL.java | 103 ++--- .../DSRC/SegmentAttributeLLDeserializer.java | 31 +- .../j2735/DSRC/SegmentAttributeLLList.java | 31 +- .../DSRC/SegmentAttributeLLSerializer.java | 31 +- .../plugin/j2735/DSRC/SegmentAttributeXY.java | 103 ++--- .../DSRC/SegmentAttributeXYDeserializer.java | 31 +- .../j2735/DSRC/SegmentAttributeXYList.java | 31 +- .../DSRC/SegmentAttributeXYSerializer.java | 31 +- .../ode/plugin/j2735/DSRC/ShapePointSet.java | 67 ++-- .../ode/plugin/j2735/DSRC/SignPrority.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/SpeedLimit.java | 31 +- .../ode/plugin/j2735/DSRC/SpeedLimitList.java | 31 +- .../plugin/j2735/DSRC/SpeedLimitSequence.java | 61 ++- .../ode/plugin/j2735/DSRC/SpeedLimitType.java | 57 +-- .../DSRC/SpeedLimitTypeDeserializer.java | 31 +- .../j2735/DSRC/SpeedLimitTypeSerializer.java | 31 +- .../plugin/j2735/DSRC/TravelerDataFrame.java | 205 ++-------- .../j2735/DSRC/TravelerDataFrame.java_bak | 355 ++++++++++++++++++ .../j2735/DSRC/TravelerDataFrameList.java | 31 +- .../plugin/j2735/DSRC/TravelerInfoType.java | 43 +-- .../DSRC/TravelerInfoTypeDeserializer.java | 31 +- .../DSRC/TravelerInfoTypeSerializer.java | 31 +- .../j2735/DSRC/TravelerInformation.java | 101 ++--- .../j2735/DSRC/TravelerInformation.java_bak | 111 ++++++ .../jpo/ode/plugin/j2735/DSRC/URL_Base.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/URL_Short.java | 31 +- .../ode/plugin/j2735/DSRC/UniqueMSGID.java | 31 +- .../ode/plugin/j2735/DSRC/ValidRegion.java | 85 ++--- .../jpo/ode/plugin/j2735/DSRC/Velocity.java | 31 +- .../jpo/ode/plugin/j2735/DSRC/WorkZone.java | 31 +- .../plugin/j2735/DSRC/WorkZoneSequence.java | 61 ++- .../its/jpo/ode/plugin/j2735/DSRC/Zoom.java | 31 +- .../jpo/ode/plugin/j2735/ITIS/ITIScodes.java | 31 +- .../plugin/j2735/ITIS/ITIScodesAndText.java | 31 +- .../j2735/ITIS/ITIScodesAndTextSequence.java | 61 ++- .../jpo/ode/plugin/j2735/ITIS/ITIStext.java | 31 +- .../plugin/j2735/REGION/Reg_ComputedLane.java | 31 +- .../j2735/REGION/Reg_GeographicalPath.java | 31 +- .../j2735/REGION/Reg_GeometricProjection.java | 31 +- .../j2735/REGION/Reg_LaneDataAttribute.java | 36 +- .../j2735/REGION/Reg_NodeAttributeSetLL.java | 31 +- .../j2735/REGION/Reg_NodeAttributeSetXY.java | 31 +- .../j2735/REGION/Reg_NodeOffsetPointLL.java | 31 +- .../j2735/REGION/Reg_NodeOffsetPointXY.java | 36 +- .../plugin/j2735/REGION/Reg_Position3D.java | 41 +- .../j2735/REGION/Reg_TravelerInformation.java | 31 +- .../its/jpo/ode/plugin/types/Asn1Field.java | 5 - 182 files changed, 4216 insertions(+), 3879 deletions(-) create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java diff --git a/jpo-ode-plugins/pom.xml b/jpo-ode-plugins/pom.xml index 50b5281d1..68716dae1 100644 --- a/jpo-ode-plugins/pom.xml +++ b/jpo-ode-plugins/pom.xml @@ -45,5 +45,8 @@ logback-core 1.4.14
+ + + diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java index 00f66faaa..90d4dfd11 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/package-info.java @@ -1,4 +1,4 @@ /** - * Annotations needed for ASN.1 UPER encoding + * Annotations for ASN.1 types */ package us.dot.its.jpo.ode.plugin.annotations; \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java index 3971504a9..ea73f2537 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DegreesLat extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java index dbfb480d2..32e97c7a2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DegreesLong extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java index 98ba42c38..21a1d67f0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Elevation extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java index ad02e6cf9..6a8596d1e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java index 7485ccd38..8cdd2bf74 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonRootName("Reg_LaneDataAttribute") diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java index 528ea1d43..f00fe29aa 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java index f33420c9e..34604a6c5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java index e1a7a2791..4afd65dcd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LatitudeDMS extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java index 3102137cb..8b256dda5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class LatitudeDMS2 extends Asn1Sequence { @Asn1Property(tag = 0) @@ -38,30 +49,6 @@ public class LatitudeDMS2 extends Asn1Sequence { @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) private SecondsAngle s; - public DegreesLat getD() { - return d; - } - - public void setD(DegreesLat d) { - this.d = d; - } - - public MinutesAngle getM() { - return m; - } - - public void setM(MinutesAngle m) { - this.m = m; - } - - public SecondsAngle getS() { - return s; - } - - public void setS(SecondsAngle s) { - this.s = s; - } - LatitudeDMS2() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java index 29d2c87b5..8a2f506b0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LongitudeDMS extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java index 91d0b02f2..7654c3a49 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class LongitudeDMS2 extends Asn1Sequence { @Asn1Property(tag = 0) @@ -38,30 +49,6 @@ public class LongitudeDMS2 extends Asn1Sequence { @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) private SecondsAngle s; - public DegreesLong getD() { - return d; - } - - public void setD(DegreesLong d) { - this.d = d; - } - - public MinutesAngle getM() { - return m; - } - - public void setM(MinutesAngle m) { - this.m = m; - } - - public SecondsAngle getS() { - return s; - } - - public void setS(SecondsAngle s) { - this.s = s; - } - LongitudeDMS2() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java index 1a559c930..c84d8d850 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MinutesAngle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java index fcbcbad4d..029269f47 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import java.util.Optional; import java.util.List; @@ -10,21 +12,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class NodeOffsetPointXY_addGrpB extends Asn1Choice { @@ -37,22 +48,6 @@ public class NodeOffsetPointXY_addGrpB extends Asn1Choice { super(true); } - public Node_LLdms_48b getPosA() { - return posA; - } - - public void setPosA(Node_LLdms_48b posA) { - this.posA = posA; - } - - public Node_LLdms_80b getPosB() { - return posB; - } - - public void setPosB(Node_LLdms_80b posB) { - this.posB = posB; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java index 7df4a3a50..bcc1722bd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonRootName("Reg_NodeOffsetPointXY") diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java index 58a329960..2344e977e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java index 5e37e5770..0f5fd8d5e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java index 1ee2af7f2..74d3f60b2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LLdms_48b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LLdms_48b extends Asn1Sequence { @JsonDeserialize(using = LatitudeDMS.LatitudeDMSDeserializer.class) private LatitudeDMS lat; - public LongitudeDMS getLon() { - return lon; - } - - public void setLon(LongitudeDMS lon) { - this.lon = lon; - } - - public LatitudeDMS getLat() { - return lat; - } - - public void setLat(LatitudeDMS lat) { - this.lat = lat; - } - Node_LLdms_48b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java index 8547424b0..b8fead586 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java @@ -4,27 +4,38 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LLdms_80b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -32,22 +43,6 @@ public class Node_LLdms_80b extends Asn1Sequence { @Asn1Property(tag = 1) private LatitudeDMS2 lat; - public LongitudeDMS2 getLon() { - return lon; - } - - public void setLon(LongitudeDMS2 lon) { - this.lon = lon; - } - - public LatitudeDMS2 getLat() { - return lat; - } - - public void setLat(LatitudeDMS2 lat) { - this.lat = lat; - } - Node_LLdms_80b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java index 95b97876b..61bbcddc3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Position3D_addGrpB extends Asn1Sequence { @Asn1Property(tag = 0) @@ -36,30 +47,6 @@ public class Position3D_addGrpB extends Asn1Sequence { @JsonDeserialize(using = Elevation.ElevationDeserializer.class) private Elevation elevation; - public LatitudeDMS2 getLatitude() { - return latitude; - } - - public void setLatitude(LatitudeDMS2 latitude) { - this.latitude = latitude; - } - - public LongitudeDMS2 getLongitude() { - return longitude; - } - - public void setLongitude(LongitudeDMS2 longitude) { - this.longitude = longitude; - } - - public Elevation getElevation() { - return elevation; - } - - public void setElevation(Elevation elevation) { - this.elevation = elevation; - } - Position3D_addGrpB() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java index 5b0f3bc27..dea08570a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonRootName("Reg_Position3D") diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java index 84496f548..323cee785 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Position3D_addGrpBReg_Position3DValueDeserializer extends OpenTypeDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java index 91fa1c891..de281a657 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Position3D_addGrpBReg_Position3DValueSerializer extends OpenTypeSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java index b59a9329c..694530556 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SecondsAngle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java index c73c8af2b..bd3ec24c7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Altitude extends Asn1Sequence { @Asn1Property(tag = 0) @@ -34,22 +45,6 @@ public class Altitude extends Asn1Sequence { @Asn1Property(tag = 1) private AltitudeConfidence confidence; - public AltitudeValue getValue() { - return value; - } - - public void setValue(AltitudeValue value) { - this.value = value; - } - - public AltitudeConfidence getConfidence() { - return confidence; - } - - public void setConfidence(AltitudeConfidence confidence) { - this.confidence = confidence; - } - Altitude() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java index 8c9bb01e5..79717dc3d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java @@ -1,47 +1,48 @@ package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = AltitudeConfidenceSerializer.class) @JsonDeserialize(using = AltitudeConfidenceDeserializer.class) public enum AltitudeConfidence implements Asn1Enumerated { - alt_000_01(0, "alt-000-01"), alt_000_02(1, "alt-000-02"), alt_000_05(2, "alt-000-05"), alt_000_10(3, - "alt-000-10"), alt_000_20(4, "alt-000-20"), alt_000_50(5, "alt-000-50"), alt_001_00(6, - "alt-001-00"), alt_002_00(7, "alt-002-00"), alt_005_00(8, "alt-005-00"), alt_010_00(9, - "alt-010-00"), alt_020_00(10, "alt-020-00"), alt_050_00(11, "alt-050-00"), alt_100_00(12, - "alt-100-00"), alt_200_00(13, - "alt-200-00"), outOfRange(14, "outOfRange"), unavailable(15, "unavailable"); + ALT_000_01(0, "alt-000-01"), ALT_000_02(1, "alt-000-02"), ALT_000_05(2, "alt-000-05"), ALT_000_10(3, + "alt-000-10"), ALT_000_20(4, "alt-000-20"), ALT_000_50(5, "alt-000-50"), ALT_001_00(6, + "alt-001-00"), ALT_002_00(7, "alt-002-00"), ALT_005_00(8, "alt-005-00"), ALT_010_00(9, + "alt-010-00"), ALT_020_00(10, "alt-020-00"), ALT_050_00(11, "alt-050-00"), ALT_100_00(12, + "alt-100-00"), ALT_200_00(13, + "alt-200-00"), OUTOFRANGE(14, "outOfRange"), UNAVAILABLE(15, "unavailable"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java index 39232d747..903cda72c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class AltitudeConfidenceDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java index 1f1722c19..a71c84133 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class AltitudeConfidenceSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java index 77a6295c1..4c7f21602 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class AltitudeValue extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java index 3d01b1604..9c271ad64 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java @@ -4,40 +4,43 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Position3D_addGrpC extends Asn1Sequence { @Asn1Property(tag = 0) private Altitude altitude; - public Altitude getAltitude() { - return altitude; - } - - public void setAltitude(Altitude altitude) { - this.altitude = altitude; - } - Position3D_addGrpC() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java index 8dd2054ca..a0cfb8ea5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonRootName("Reg_Position3D") diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java index 9d9d8995c..86fd9fcc9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Position3D_addGrpCReg_Position3DValueDeserializer extends OpenTypeDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java index 0345169aa..6de20e887 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Position3D_addGrpCReg_Position3DValueSerializer extends OpenTypeSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java index 747b3c136..d0dc9dd0d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Angle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java index e90e05107..32d6f2325 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Circle extends Asn1Sequence { @Asn1Property(tag = 0) @@ -36,30 +47,6 @@ public class Circle extends Asn1Sequence { @Asn1Property(tag = 2) private DistanceUnits units; - public Position3D getCenter() { - return center; - } - - public void setCenter(Position3D center) { - this.center = center; - } - - public Radius_B12 getRadius() { - return radius; - } - - public void setRadius(Radius_B12 radius) { - this.radius = radius; - } - - public DistanceUnits getUnits() { - return units; - } - - public void setUnits(DistanceUnits units) { - this.units = units; - } - Circle() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java index fa9decec4..843a44660 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; @@ -15,23 +17,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class ComputedLane extends Asn1Sequence { @Asn1Property(tag = 0) @@ -53,14 +64,8 @@ public class ComputedLane extends Asn1Sequence { @Asn1Property(tag = 6, optional = true) private SequenceOfRegional regional; - public LaneID getReferenceLaneId() { - return referenceLaneId; - } - - public void setReferenceLaneId(LaneID referenceLaneId) { - this.referenceLaneId = referenceLaneId; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class OffsetXaxisChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -74,36 +79,14 @@ public static class OffsetXaxisChoice extends Asn1Choice { super(false); } - public DrivenLineOffsetSm getSmall() { - return small; - } - - public void setSmall(DrivenLineOffsetSm small) { - this.small = small; - } - - public DrivenLineOffsetLg getLarge() { - return large; - } - - public void setLarge(DrivenLineOffsetLg large) { - this.large = large; - } - @Override protected List> listTypes() { return null; } } - public OffsetXaxisChoice getOffsetXaxis() { - return offsetXaxis; - } - - public void setOffsetXaxis(OffsetXaxisChoice offsetXaxis) { - this.offsetXaxis = offsetXaxis; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class OffsetYaxisChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -117,75 +100,19 @@ public static class OffsetYaxisChoice extends Asn1Choice { super(false); } - public DrivenLineOffsetSm getSmall() { - return small; - } - - public void setSmall(DrivenLineOffsetSm small) { - this.small = small; - } - - public DrivenLineOffsetLg getLarge() { - return large; - } - - public void setLarge(DrivenLineOffsetLg large) { - this.large = large; - } - @Override protected List> listTypes() { return null; } } - public OffsetYaxisChoice getOffsetYaxis() { - return offsetYaxis; - } - - public void setOffsetYaxis(OffsetYaxisChoice offsetYaxis) { - this.offsetYaxis = offsetYaxis; - } - - public Angle getRotateXY() { - return rotateXY; - } - - public void setRotateXY(Angle rotateXY) { - this.rotateXY = rotateXY; - } - - public Scale_B12 getScaleXaxis() { - return scaleXaxis; - } - - public void setScaleXaxis(Scale_B12 scaleXaxis) { - this.scaleXaxis = scaleXaxis; - } - - public Scale_B12 getScaleYaxis() { - return scaleYaxis; - } - - public void setScaleYaxis(Scale_B12 scaleYaxis) { - this.scaleYaxis = scaleYaxis; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_ComputedLane.class, 1L, 4L); + super(Reg_ComputedLane.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - ComputedLane() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java index f5194d6d0..302c1f6c4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DYear extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java index ad7b4d24d..5d632870f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DeltaAngle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java index 3816bb79f..209d62c92 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DescriptiveName extends IA5String { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java index 87d53e48d..46e7b4757 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java @@ -1,42 +1,43 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = DirectionOfUseSerializer.class) @JsonDeserialize(using = DirectionOfUseDeserializer.class) public enum DirectionOfUse implements Asn1Enumerated { - unavailable(0, "unavailable"), forward(1, "forward"), reverse(2, "reverse"), both(3, "both"); + UNAVAILABLE(0, "unavailable"), FORWARD(1, "forward"), REVERSE(2, "reverse"), BOTH(3, "both"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java index 22e4c7c3d..e9ff794f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DirectionOfUseDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java index ddf1dde5b..1337c92ab 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DirectionOfUseSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java index 07ab86509..4051b56c6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java @@ -1,43 +1,44 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = DistanceUnitsSerializer.class) @JsonDeserialize(using = DistanceUnitsDeserializer.class) public enum DistanceUnits implements Asn1Enumerated { - centimeter(0, "centimeter"), cm2_5(1, "cm2-5"), decimeter(2, "decimeter"), meter(3, "meter"), kilometer(4, - "kilometer"), foot(5, "foot"), yard(6, "yard"), mile(7, "mile"); + CENTIMETER(0, "centimeter"), CM2_5(1, "cm2-5"), DECIMETER(2, "decimeter"), METER(3, "meter"), KILOMETER(4, + "kilometer"), FOOT(5, "foot"), YARD(6, "yard"), MILE(7, "mile"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java index 75b2923fa..2fe639254 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DistanceUnitsDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java index e9cd7bad2..1214e84de 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DistanceUnitsSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java index 0f8447119..bde781fb0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DrivenLineOffsetLg extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java index ff8e342c0..8a0c983d1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class DrivenLineOffsetSm extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java index 64d9b20f3..fe6af2266 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Elevation extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java index 99e2e3637..9eb660042 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java index 0c2987237..e5bc0b622 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java @@ -9,33 +9,46 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class ExitServiceSequence extends Asn1Sequence { @Asn1Property(tag = 0) private ItemChoice item; + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -48,36 +61,12 @@ public static class ItemChoice extends Asn1Choice { super(false); } - public ITIScodes getItis() { - return itis; - } - - public void setItis(ITIScodes itis) { - this.itis = itis; - } - - public ITIStextPhrase getText() { - return text; - } - - public void setText(ITIStextPhrase text) { - this.text = text; - } - @Override protected List> listTypes() { return null; } } - public ItemChoice getItem() { - return item; - } - - public void setItem(ItemChoice item) { - this.item = item; - } - ExitServiceSequence() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java index 2c57b326a..3b6af79ff 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java @@ -1,52 +1,53 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = ExtentSerializer.class) @JsonDeserialize(using = ExtentDeserializer.class) public enum Extent implements Asn1Enumerated { - useInstantlyOnly(0, "useInstantlyOnly"), useFor3meters(1, "useFor3meters"), useFor10meters(2, - "useFor10meters"), useFor50meters(3, "useFor50meters"), useFor100meters(4, - "useFor100meters"), useFor500meters(5, "useFor500meters"), useFor1000meters(6, - "useFor1000meters"), useFor5000meters(7, "useFor5000meters"), useFor10000meters(8, - "useFor10000meters"), useFor50000meters(9, "useFor50000meters"), useFor100000meters( - 10, "useFor100000meters"), useFor500000meters(11, - "useFor500000meters"), useFor1000000meters(12, - "useFor1000000meters"), useFor5000000meters(13, - "useFor5000000meters"), useFor10000000meters(14, - "useFor10000000meters"), forever(15, + USEINSTANTLYONLY(0, "useInstantlyOnly"), USEFOR3METERS(1, "useFor3meters"), USEFOR10METERS(2, + "useFor10meters"), USEFOR50METERS(3, "useFor50meters"), USEFOR100METERS(4, + "useFor100meters"), USEFOR500METERS(5, "useFor500meters"), USEFOR1000METERS(6, + "useFor1000meters"), USEFOR5000METERS(7, "useFor5000meters"), USEFOR10000METERS(8, + "useFor10000meters"), USEFOR50000METERS(9, "useFor50000meters"), USEFOR100000METERS( + 10, "useFor100000meters"), USEFOR500000METERS(11, + "useFor500000meters"), USEFOR1000000METERS(12, + "useFor1000000meters"), USEFOR5000000METERS(13, + "useFor5000000meters"), USEFOR10000000METERS(14, + "useFor10000000meters"), FOREVER(15, "forever"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java index dd18b82e4..27adb0aca 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class ExtentDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java index 955baaf1f..2ff569353 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class ExtentSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java index f9c733971..e15b0e398 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class FurtherInfoID extends Asn1OctetString { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java index bc5b22371..c9a1f2e48 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java index 4dda92563..b7c3e3aca 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java @@ -9,33 +9,46 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class GenericSignageSequence extends Asn1Sequence { @Asn1Property(tag = 0) private ItemChoice item; + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -48,36 +61,12 @@ public static class ItemChoice extends Asn1Choice { super(false); } - public ITIScodes getItis() { - return itis; - } - - public void setItis(ITIScodes itis) { - this.itis = itis; - } - - public ITIStextPhrase getText() { - return text; - } - - public void setText(ITIStextPhrase text) { - this.text = text; - } - @Override protected List> listTypes() { return null; } } - public ItemChoice getItem() { - return item; - } - - public void setItem(ItemChoice item) { - this.item = item; - } - GenericSignageSequence() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java index 8cbee9e51..9d3d12b49 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; @@ -16,23 +18,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class GeographicalPath extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -55,62 +66,8 @@ public class GeographicalPath extends Asn1Sequence { @Asn1Property(tag = 8, optional = true) private SequenceOfRegional regional; - public DescriptiveName getName() { - return name; - } - - public void setName(DescriptiveName name) { - this.name = name; - } - - public RoadSegmentReferenceID getId() { - return id; - } - - public void setId(RoadSegmentReferenceID id) { - this.id = id; - } - - public Position3D getAnchor() { - return anchor; - } - - public void setAnchor(Position3D anchor) { - this.anchor = anchor; - } - - public LaneWidth getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(LaneWidth laneWidth) { - this.laneWidth = laneWidth; - } - - public DirectionOfUse getDirectionality() { - return directionality; - } - - public void setDirectionality(DirectionOfUse directionality) { - this.directionality = directionality; - } - - public Asn1Boolean getClosedPath() { - return closedPath; - } - - public void setClosedPath(Asn1Boolean closedPath) { - this.closedPath = closedPath; - } - - public HeadingSlice getDirection() { - return direction; - } - - public void setDirection(HeadingSlice direction) { - this.direction = direction; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class DescriptionChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -124,59 +81,19 @@ public static class DescriptionChoice extends Asn1Choice { super(true); } - public OffsetSystem getPath() { - return path; - } - - public void setPath(OffsetSystem path) { - this.path = path; - } - - public GeometricProjection getGeometry() { - return geometry; - } - - public void setGeometry(GeometricProjection geometry) { - this.geometry = geometry; - } - - public ValidRegion getOldRegion() { - return oldRegion; - } - - public void setOldRegion(ValidRegion oldRegion) { - this.oldRegion = oldRegion; - } - @Override protected List> listTypes() { return null; } } - public DescriptionChoice getDescription() { - return description; - } - - public void setDescription(DescriptionChoice description) { - this.description = description; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeographicalPath.class, 1L, 4L); + super(Reg_GeographicalPath.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - GeographicalPath() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java index 63805fcda..4d61a2b9b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeometricProjection; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; @@ -11,23 +13,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class GeometricProjection extends Asn1Sequence { @Asn1Property(tag = 0) @@ -42,53 +53,13 @@ public class GeometricProjection extends Asn1Sequence { @Asn1Property(tag = 4, optional = true) private SequenceOfRegional regional; - public HeadingSlice getDirection() { - return direction; - } - - public void setDirection(HeadingSlice direction) { - this.direction = direction; - } - - public Extent getExtent() { - return extent; - } - - public void setExtent(Extent extent) { - this.extent = extent; - } - - public LaneWidth getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(LaneWidth laneWidth) { - this.laneWidth = laneWidth; - } - - public Circle getCircle() { - return circle; - } - - public void setCircle(Circle circle) { - this.circle = circle; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeometricProjection.class, 1L, 4L); + super(Reg_GeometricProjection.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - GeometricProjection() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java index bc4993ac9..8ded5b3c7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonDeserialize(using = HeadingSliceDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java index f34c946c5..9c307388d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class HeadingSliceDeserializer extends BitStringDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java index ffff1a3a1..b84fbb099 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class ITIStextPhrase extends IA5String { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java index 72f01b53e..9da23b8cf 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; @@ -15,21 +17,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class LaneDataAttribute extends Asn1Choice { @@ -59,69 +70,13 @@ public class LaneDataAttribute extends Asn1Choice { super(true); } - public DeltaAngle getPathEndPointAngle() { - return pathEndPointAngle; - } - - public void setPathEndPointAngle(DeltaAngle pathEndPointAngle) { - this.pathEndPointAngle = pathEndPointAngle; - } - - public RoadwayCrownAngle getLaneCrownPointCenter() { - return laneCrownPointCenter; - } - - public void setLaneCrownPointCenter(RoadwayCrownAngle laneCrownPointCenter) { - this.laneCrownPointCenter = laneCrownPointCenter; - } - - public RoadwayCrownAngle getLaneCrownPointLeft() { - return laneCrownPointLeft; - } - - public void setLaneCrownPointLeft(RoadwayCrownAngle laneCrownPointLeft) { - this.laneCrownPointLeft = laneCrownPointLeft; - } - - public RoadwayCrownAngle getLaneCrownPointRight() { - return laneCrownPointRight; - } - - public void setLaneCrownPointRight(RoadwayCrownAngle laneCrownPointRight) { - this.laneCrownPointRight = laneCrownPointRight; - } - - public MergeDivergeNodeAngle getLaneAngle() { - return laneAngle; - } - - public void setLaneAngle(MergeDivergeNodeAngle laneAngle) { - this.laneAngle = laneAngle; - } - - public SpeedLimitList getSpeedLimits() { - return speedLimits; - } - - public void setSpeedLimits(SpeedLimitList speedLimits) { - this.speedLimits = speedLimits; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute.class, 1L, 4L); + super(Reg_LaneDataAttribute.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java index b9511ad3c..d3b770fc7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java index fe1570546..721c384e2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LaneID extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java index ea4f92b16..eed9f59e3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class LaneWidth extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java index 412c4005c..df8cd9661 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Latitude extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java index a0edc9d62..15f170200 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Longitude extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java index 6fcac726b..7dba15957 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java @@ -1,43 +1,44 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = MUTCDCodeSerializer.class) @JsonDeserialize(using = MUTCDCodeDeserializer.class) public enum MUTCDCode implements Asn1Enumerated { - none(0, "none"), regulatory(1, "regulatory"), warning(2, "warning"), maintenance(3, - "maintenance"), motoristService(4, "motoristService"), guide(5, "guide"), rec(6, "rec"); + NONE(0, "none"), REGULATORY(1, "regulatory"), WARNING(2, "warning"), MAINTENANCE(3, + "maintenance"), MOTORISTSERVICE(4, "motoristService"), GUIDE(5, "guide"), REC(6, "rec"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java index 0ab54e0aa..b67f017c5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MUTCDCodeDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java index 25d9dc376..4ee4a94b4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MUTCDCodeSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java index 3f3f60175..e5886ccc0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MergeDivergeNodeAngle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java index acad5bdda..47ace2e45 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MinuteOfTheYear extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java index 5a09cc75c..63664052a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MinutesDuration extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java index 292d0400e..6606f5ec8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MsgCRC extends Asn1OctetString { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java index d10c6c481..c34e0b6ef 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class MsgCount extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java index 88cc1d2b1..573e8f895 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java @@ -1,46 +1,47 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = NodeAttributeLLSerializer.class) @JsonDeserialize(using = NodeAttributeLLDeserializer.class) public enum NodeAttributeLL implements Asn1Enumerated { - reserved(0, "reserved"), stopLine(1, "stopLine"), roundedCapStyleA(2, "roundedCapStyleA"), roundedCapStyleB(3, - "roundedCapStyleB"), mergePoint(4, "mergePoint"), divergePoint(5, "divergePoint"), downstreamStopLine(6, - "downstreamStopLine"), downstreamStartNode(7, "downstreamStartNode"), closedToTraffic(8, - "closedToTraffic"), safeIsland(9, "safeIsland"), curbPresentAtStepOff(10, - "curbPresentAtStepOff"), hydrantPresent(11, "hydrantPresent"); + RESERVED(0, "reserved"), STOPLINE(1, "stopLine"), ROUNDEDCAPSTYLEA(2, "roundedCapStyleA"), ROUNDEDCAPSTYLEB(3, + "roundedCapStyleB"), MERGEPOINT(4, "mergePoint"), DIVERGEPOINT(5, "divergePoint"), DOWNSTREAMSTOPLINE(6, + "downstreamStopLine"), DOWNSTREAMSTARTNODE(7, "downstreamStartNode"), CLOSEDTOTRAFFIC(8, + "closedToTraffic"), SAFEISLAND(9, "safeIsland"), CURBPRESENTATSTEPOFF(10, + "curbPresentAtStepOff"), HYDRANTPRESENT(11, "hydrantPresent"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java index f1a7211b2..9854db23f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeAttributeLLDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java index 6fc8d6a7e..29f77a0bd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java index c1248cb00..e616bbd24 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeAttributeLLSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java index 1225b6c2b..2617746dd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetLL; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; @@ -12,23 +14,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class NodeAttributeSetLL extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -52,69 +63,13 @@ public class NodeAttributeSetLL extends Asn1Sequence { @Asn1Property(tag = 6, optional = true) private SequenceOfRegional regional; - public NodeAttributeLLList getLocalNode() { - return localNode; - } - - public void setLocalNode(NodeAttributeLLList localNode) { - this.localNode = localNode; - } - - public SegmentAttributeLLList getDisabled() { - return disabled; - } - - public void setDisabled(SegmentAttributeLLList disabled) { - this.disabled = disabled; - } - - public SegmentAttributeLLList getEnabled() { - return enabled; - } - - public void setEnabled(SegmentAttributeLLList enabled) { - this.enabled = enabled; - } - - public LaneDataAttributeList getData() { - return data; - } - - public void setData(LaneDataAttributeList data) { - this.data = data; - } - - public Offset_B10 getDWidth() { - return dWidth; - } - - public void setDWidth(Offset_B10 dWidth) { - this.dWidth = dWidth; - } - - public Offset_B10 getDElevation() { - return dElevation; - } - - public void setDElevation(Offset_B10 dElevation) { - this.dElevation = dElevation; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetLL.class, 1L, 4L); + super(Reg_NodeAttributeSetLL.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - NodeAttributeSetLL() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java index 90d7fdf5f..3a0bcece0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetXY; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; @@ -12,23 +14,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class NodeAttributeSetXY extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -52,69 +63,13 @@ public class NodeAttributeSetXY extends Asn1Sequence { @Asn1Property(tag = 6, optional = true) private SequenceOfRegional regional; - public NodeAttributeXYList getLocalNode() { - return localNode; - } - - public void setLocalNode(NodeAttributeXYList localNode) { - this.localNode = localNode; - } - - public SegmentAttributeXYList getDisabled() { - return disabled; - } - - public void setDisabled(SegmentAttributeXYList disabled) { - this.disabled = disabled; - } - - public SegmentAttributeXYList getEnabled() { - return enabled; - } - - public void setEnabled(SegmentAttributeXYList enabled) { - this.enabled = enabled; - } - - public LaneDataAttributeList getData() { - return data; - } - - public void setData(LaneDataAttributeList data) { - this.data = data; - } - - public Offset_B10 getDWidth() { - return dWidth; - } - - public void setDWidth(Offset_B10 dWidth) { - this.dWidth = dWidth; - } - - public Offset_B10 getDElevation() { - return dElevation; - } - - public void setDElevation(Offset_B10 dElevation) { - this.dElevation = dElevation; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetXY.class, 1L, 4L); + super(Reg_NodeAttributeSetXY.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - NodeAttributeSetXY() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java index b404926b1..b71a0694f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java @@ -1,46 +1,47 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = NodeAttributeXYSerializer.class) @JsonDeserialize(using = NodeAttributeXYDeserializer.class) public enum NodeAttributeXY implements Asn1Enumerated { - reserved(0, "reserved"), stopLine(1, "stopLine"), roundedCapStyleA(2, "roundedCapStyleA"), roundedCapStyleB(3, - "roundedCapStyleB"), mergePoint(4, "mergePoint"), divergePoint(5, "divergePoint"), downstreamStopLine(6, - "downstreamStopLine"), downstreamStartNode(7, "downstreamStartNode"), closedToTraffic(8, - "closedToTraffic"), safeIsland(9, "safeIsland"), curbPresentAtStepOff(10, - "curbPresentAtStepOff"), hydrantPresent(11, "hydrantPresent"); + RESERVED(0, "reserved"), STOPLINE(1, "stopLine"), ROUNDEDCAPSTYLEA(2, "roundedCapStyleA"), ROUNDEDCAPSTYLEB(3, + "roundedCapStyleB"), MERGEPOINT(4, "mergePoint"), DIVERGEPOINT(5, "divergePoint"), DOWNSTREAMSTOPLINE(6, + "downstreamStopLine"), DOWNSTREAMSTARTNODE(7, "downstreamStartNode"), CLOSEDTOTRAFFIC(8, + "closedToTraffic"), SAFEISLAND(9, "safeIsland"), CURBPRESENTATSTEPOFF(10, + "curbPresentAtStepOff"), HYDRANTPRESENT(11, "hydrantPresent"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java index e4e7cde86..92875722d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeAttributeXYDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java index 311899d28..0cf0e274c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java index 35d331c1c..f44a009a9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class NodeAttributeXYSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java index be8451ddf..32ab8e66c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java @@ -4,27 +4,38 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class NodeLL extends Asn1Sequence { @Asn1Property(tag = 0) @@ -32,22 +43,6 @@ public class NodeLL extends Asn1Sequence { @Asn1Property(tag = 1, optional = true) private NodeAttributeSetLL attributes; - public NodeOffsetPointLL getDelta() { - return delta; - } - - public void setDelta(NodeOffsetPointLL delta) { - this.delta = delta; - } - - public NodeAttributeSetLL getAttributes() { - return attributes; - } - - public void setAttributes(NodeAttributeSetLL attributes) { - this.attributes = attributes; - } - NodeLL() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java index dfcc6f6d8..9cc390cd7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import java.util.Optional; import java.util.List; @@ -12,21 +14,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class NodeListLL extends Asn1Choice { @@ -39,14 +50,6 @@ public class NodeListLL extends Asn1Choice { super(true); } - public NodeSetLL getNodes() { - return nodes; - } - - public void setNodes(NodeSetLL nodes) { - this.nodes = nodes; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java index 8c1389e32..ee341ab76 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import java.util.Optional; import java.util.List; @@ -12,21 +14,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class NodeListXY extends Asn1Choice { @@ -41,22 +52,6 @@ public class NodeListXY extends Asn1Choice { super(true); } - public NodeSetXY getNodes() { - return nodes; - } - - public void setNodes(NodeSetXY nodes) { - this.nodes = nodes; - } - - public ComputedLane getComputed() { - return computed; - } - - public void setComputed(ComputedLane computed) { - this.computed = computed; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java index b7c789e95..bae1cd87a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointLL; @@ -12,21 +14,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class NodeOffsetPointLL extends Asn1Choice { @@ -58,70 +69,6 @@ public class NodeOffsetPointLL extends Asn1Choice { super(false); } - public Node_LL_24B getNode_LL1() { - return node_LL1; - } - - public void setNode_LL1(Node_LL_24B node_LL1) { - this.node_LL1 = node_LL1; - } - - public Node_LL_28B getNode_LL2() { - return node_LL2; - } - - public void setNode_LL2(Node_LL_28B node_LL2) { - this.node_LL2 = node_LL2; - } - - public Node_LL_32B getNode_LL3() { - return node_LL3; - } - - public void setNode_LL3(Node_LL_32B node_LL3) { - this.node_LL3 = node_LL3; - } - - public Node_LL_36B getNode_LL4() { - return node_LL4; - } - - public void setNode_LL4(Node_LL_36B node_LL4) { - this.node_LL4 = node_LL4; - } - - public Node_LL_44B getNode_LL5() { - return node_LL5; - } - - public void setNode_LL5(Node_LL_44B node_LL5) { - this.node_LL5 = node_LL5; - } - - public Node_LL_48B getNode_LL6() { - return node_LL6; - } - - public void setNode_LL6(Node_LL_48B node_LL6) { - this.node_LL6 = node_LL6; - } - - public Node_LLmD_64b getNode_LatLon() { - return node_LatLon; - } - - public void setNode_LatLon(Node_LLmD_64b node_LatLon) { - this.node_LatLon = node_LatLon; - } - - public Reg_NodeOffsetPointLL getRegional() { - return regional; - } - - public void setRegional(Reg_NodeOffsetPointLL regional) { - this.regional = regional; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java index 834ab5f18..e3a1db4ef 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java @@ -1,6 +1,8 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointXY; @@ -12,21 +14,30 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter +@Setter @JsonInclude(Include.NON_NULL) public class NodeOffsetPointXY extends Asn1Choice { @@ -58,70 +69,6 @@ public class NodeOffsetPointXY extends Asn1Choice { super(false); } - public Node_XY_20b getNode_XY1() { - return node_XY1; - } - - public void setNode_XY1(Node_XY_20b node_XY1) { - this.node_XY1 = node_XY1; - } - - public Node_XY_22b getNode_XY2() { - return node_XY2; - } - - public void setNode_XY2(Node_XY_22b node_XY2) { - this.node_XY2 = node_XY2; - } - - public Node_XY_24b getNode_XY3() { - return node_XY3; - } - - public void setNode_XY3(Node_XY_24b node_XY3) { - this.node_XY3 = node_XY3; - } - - public Node_XY_26b getNode_XY4() { - return node_XY4; - } - - public void setNode_XY4(Node_XY_26b node_XY4) { - this.node_XY4 = node_XY4; - } - - public Node_XY_28b getNode_XY5() { - return node_XY5; - } - - public void setNode_XY5(Node_XY_28b node_XY5) { - this.node_XY5 = node_XY5; - } - - public Node_XY_32b getNode_XY6() { - return node_XY6; - } - - public void setNode_XY6(Node_XY_32b node_XY6) { - this.node_XY6 = node_XY6; - } - - public Node_LLmD_64b getNode_LatLon() { - return node_LatLon; - } - - public void setNode_LatLon(Node_LLmD_64b node_LatLon) { - this.node_LatLon = node_LatLon; - } - - public Reg_NodeOffsetPointXY getRegional() { - return regional; - } - - public void setRegional(Reg_NodeOffsetPointXY regional) { - this.regional = regional; - } - @Override protected List> listTypes() { return null; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java index 2e81ff5d0..83eaa5b1b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java index 880fcbac7..c61b29358 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java index cc421bf85..8d515eebb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java @@ -4,27 +4,38 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class NodeXY extends Asn1Sequence { @Asn1Property(tag = 0) @@ -32,22 +43,6 @@ public class NodeXY extends Asn1Sequence { @Asn1Property(tag = 1, optional = true) private NodeAttributeSetXY attributes; - public NodeOffsetPointXY getDelta() { - return delta; - } - - public void setDelta(NodeOffsetPointXY delta) { - this.delta = delta; - } - - public NodeAttributeSetXY getAttributes() { - return attributes; - } - - public void setAttributes(NodeAttributeSetXY attributes) { - this.attributes = attributes; - } - NodeXY() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java index cafdac04e..efafc4339 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_24B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_24B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) private OffsetLL_B12 lat; - public OffsetLL_B12 getLon() { - return lon; - } - - public void setLon(OffsetLL_B12 lon) { - this.lon = lon; - } - - public OffsetLL_B12 getLat() { - return lat; - } - - public void setLat(OffsetLL_B12 lat) { - this.lat = lat; - } - Node_LL_24B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java index 4aa6d9b66..fae4ecdbb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_28B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_28B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) private OffsetLL_B14 lat; - public OffsetLL_B14 getLon() { - return lon; - } - - public void setLon(OffsetLL_B14 lon) { - this.lon = lon; - } - - public OffsetLL_B14 getLat() { - return lat; - } - - public void setLat(OffsetLL_B14 lat) { - this.lat = lat; - } - Node_LL_28B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java index bb16587be..df36b4c3a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_32B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_32B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) private OffsetLL_B16 lat; - public OffsetLL_B16 getLon() { - return lon; - } - - public void setLon(OffsetLL_B16 lon) { - this.lon = lon; - } - - public OffsetLL_B16 getLat() { - return lat; - } - - public void setLat(OffsetLL_B16 lat) { - this.lat = lat; - } - Node_LL_32B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java index 2397c1578..6583e78a5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_36B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_36B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) private OffsetLL_B18 lat; - public OffsetLL_B18 getLon() { - return lon; - } - - public void setLon(OffsetLL_B18 lon) { - this.lon = lon; - } - - public OffsetLL_B18 getLat() { - return lat; - } - - public void setLat(OffsetLL_B18 lat) { - this.lat = lat; - } - Node_LL_36B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java index 2646045ff..a14c641db 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_44B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_44B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) private OffsetLL_B22 lat; - public OffsetLL_B22 getLon() { - return lon; - } - - public void setLon(OffsetLL_B22 lon) { - this.lon = lon; - } - - public OffsetLL_B22 getLat() { - return lat; - } - - public void setLat(OffsetLL_B22 lat) { - this.lat = lat; - } - Node_LL_44B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java index ea50e345e..e5946e86d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LL_48B extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LL_48B extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) private OffsetLL_B24 lat; - public OffsetLL_B24 getLon() { - return lon; - } - - public void setLon(OffsetLL_B24 lon) { - this.lon = lon; - } - - public OffsetLL_B24 getLat() { - return lat; - } - - public void setLat(OffsetLL_B24 lat) { - this.lat = lat; - } - Node_LL_48B() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java index 2606a44da..ba38d3954 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_LLmD_64b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_LLmD_64b extends Asn1Sequence { @JsonDeserialize(using = Latitude.LatitudeDeserializer.class) private Latitude lat; - public Longitude getLon() { - return lon; - } - - public void setLon(Longitude lon) { - this.lon = lon; - } - - public Latitude getLat() { - return lat; - } - - public void setLat(Latitude lat) { - this.lat = lat; - } - Node_LLmD_64b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java index f17e29f10..67f04a51f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_20b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_20b extends Asn1Sequence { @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) private Offset_B10 y; - public Offset_B10 getX() { - return x; - } - - public void setX(Offset_B10 x) { - this.x = x; - } - - public Offset_B10 getY() { - return y; - } - - public void setY(Offset_B10 y) { - this.y = y; - } - Node_XY_20b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java index 22f230750..8a10cfc34 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_22b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_22b extends Asn1Sequence { @JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) private Offset_B11 y; - public Offset_B11 getX() { - return x; - } - - public void setX(Offset_B11 x) { - this.x = x; - } - - public Offset_B11 getY() { - return y; - } - - public void setY(Offset_B11 y) { - this.y = y; - } - Node_XY_22b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java index 4f3496f66..9d9a5f16d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_24b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_24b extends Asn1Sequence { @JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) private Offset_B12 y; - public Offset_B12 getX() { - return x; - } - - public void setX(Offset_B12 x) { - this.x = x; - } - - public Offset_B12 getY() { - return y; - } - - public void setY(Offset_B12 y) { - this.y = y; - } - Node_XY_24b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java index ba0775433..a38aa0ff0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_26b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_26b extends Asn1Sequence { @JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) private Offset_B13 y; - public Offset_B13 getX() { - return x; - } - - public void setX(Offset_B13 x) { - this.x = x; - } - - public Offset_B13 getY() { - return y; - } - - public void setY(Offset_B13 y) { - this.y = y; - } - Node_XY_26b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java index 4ce74eb15..0847fbdeb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_28b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_28b extends Asn1Sequence { @JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) private Offset_B14 y; - public Offset_B14 getX() { - return x; - } - - public void setX(Offset_B14 x) { - this.x = x; - } - - public Offset_B14 getY() { - return y; - } - - public void setY(Offset_B14 y) { - this.y = y; - } - Node_XY_28b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java index 90ee3098a..15f837c63 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Node_XY_32b extends Asn1Sequence { @Asn1Property(tag = 0) @@ -35,22 +46,6 @@ public class Node_XY_32b extends Asn1Sequence { @JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) private Offset_B16 y; - public Offset_B16 getX() { - return x; - } - - public void setX(Offset_B16 x) { - this.x = x; - } - - public Offset_B16 getY() { - return y; - } - - public void setY(Offset_B16 y) { - this.y = y; - } - Node_XY_32b() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java index f282c913d..b5e1d9638 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B12 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java index b072d3e1c..bed70b10b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B14 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java index 858fe7db1..f387a6f5b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B16 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java index a3c10390d..89976805d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B18 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java index e7cb154cf..0c68b8470 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B22 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java index 43fc5e189..e7e3320f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class OffsetLL_B24 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java index 97f5bec2e..ad999cc1e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; @@ -13,23 +15,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class OffsetSystem extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -38,14 +49,8 @@ public class OffsetSystem extends Asn1Sequence { @Asn1Property(tag = 1) private OffsetChoice offset; - public Zoom getScale() { - return scale; - } - - public void setScale(Zoom scale) { - this.scale = scale; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class OffsetChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -57,36 +62,12 @@ public static class OffsetChoice extends Asn1Choice { super(false); } - public NodeListXY getXy() { - return xy; - } - - public void setXy(NodeListXY xy) { - this.xy = xy; - } - - public NodeListLL getLl() { - return ll; - } - - public void setLl(NodeListLL ll) { - this.ll = ll; - } - @Override protected List> listTypes() { return null; } } - public OffsetChoice getOffset() { - return offset; - } - - public void setOffset(OffsetChoice offset) { - this.offset = offset; - } - OffsetSystem() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java index ad6e0e1bd..7059da2c5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B10 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java index 7e725904b..b475f1ae7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B11 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java index 1e3b29519..363dc133f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B12 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java index 97cee3e55..f825ac517 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B13 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java index 1c16d7d4a..0c006d132 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B14 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java index 78413d799..d0d02996d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Offset_B16 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java index 1bc3db597..d69ca2954 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; @@ -12,23 +14,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class Position3D extends Asn1Sequence { @Asn1Property(tag = 0) @@ -44,45 +55,13 @@ public class Position3D extends Asn1Sequence { @Asn1Property(tag = 3, optional = true) private SequenceOfRegional regional; - public Latitude getLat() { - return lat; - } - - public void setLat(Latitude lat) { - this.lat = lat; - } - - public Longitude getLong_() { - return long_; - } - - public void setLong_(Longitude long_) { - this.long_ = long_; - } - - public Elevation getElevation() { - return elevation; - } - - public void setElevation(Elevation elevation) { - this.elevation = elevation; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D.class, 1L, 4L); + super(Reg_Position3D.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - Position3D() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java index 3afbfed59..c328df226 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Radius_B12 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java index 82bbe65ef..6213f3ea2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class RegionId extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java index 2a179fda2..0bf8005f0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java index 61437bc13..6adab3e16 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class RegionOffsets extends Asn1Sequence { @Asn1Property(tag = 0) @@ -38,30 +49,6 @@ public class RegionOffsets extends Asn1Sequence { @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) private OffsetLL_B16 zOffset; - public OffsetLL_B16 getXOffset() { - return xOffset; - } - - public void setXOffset(OffsetLL_B16 xOffset) { - this.xOffset = xOffset; - } - - public OffsetLL_B16 getYOffset() { - return yOffset; - } - - public void setYOffset(OffsetLL_B16 yOffset) { - this.yOffset = yOffset; - } - - public OffsetLL_B16 getZOffset() { - return zOffset; - } - - public void setZOffset(OffsetLL_B16 zOffset) { - this.zOffset = zOffset; - } - RegionOffsets() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java index a2c133bfb..30cf329b1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; @@ -11,23 +13,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class RegionPointSet extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -40,30 +51,6 @@ public class RegionPointSet extends Asn1Sequence { @JacksonXmlProperty(localName = "RegionOffsets") private RegionList nodeList; - public Position3D getAnchor() { - return anchor; - } - - public void setAnchor(Position3D anchor) { - this.anchor = anchor; - } - - public Zoom getScale() { - return scale; - } - - public void setScale(Zoom scale) { - this.scale = scale; - } - - public RegionList getNodeList() { - return nodeList; - } - - public void setNodeList(RegionList nodeList) { - this.nodeList = nodeList; - } - RegionPointSet() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java index 2c029c459..707a1e3f7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ abstract public class RegionalExtension extends Asn1Sequence { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java index 752adcad7..44214b7b6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class RegulatorySpeedLimit extends Asn1Sequence { @Asn1Property(tag = 0) @@ -34,22 +45,6 @@ public class RegulatorySpeedLimit extends Asn1Sequence { @JsonDeserialize(using = Velocity.VelocityDeserializer.class) private Velocity speed; - public SpeedLimitType getType() { - return type; - } - - public void setType(SpeedLimitType type) { - this.type = type; - } - - public Velocity getSpeed() { - return speed; - } - - public void setSpeed(Velocity speed) { - this.speed = speed; - } - RegulatorySpeedLimit() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java index cbc2e5cc0..69a71723a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class RoadRegulatorID extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java index e776a933c..1600c20bf 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class RoadSegmentID extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java index 5ba6bfc45..9d6a4c0d6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class RoadSegmentReferenceID extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -35,22 +46,6 @@ public class RoadSegmentReferenceID extends Asn1Sequence { @JsonDeserialize(using = RoadSegmentID.RoadSegmentIDDeserializer.class) private RoadSegmentID id; - public RoadRegulatorID getRegion() { - return region; - } - - public void setRegion(RoadRegulatorID region) { - this.region = region; - } - - public RoadSegmentID getId() { - return id; - } - - public void setId(RoadSegmentID id) { - this.id = id; - } - RoadSegmentReferenceID() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java index c934089d4..de9148479 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java @@ -4,27 +4,38 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class RoadSignID extends Asn1Sequence { @Asn1Property(tag = 0) @@ -36,38 +47,6 @@ public class RoadSignID extends Asn1Sequence { @Asn1Property(tag = 3, optional = true) private MsgCRC crc; - public Position3D getPosition() { - return position; - } - - public void setPosition(Position3D position) { - this.position = position; - } - - public HeadingSlice getViewAngle() { - return viewAngle; - } - - public void setViewAngle(HeadingSlice viewAngle) { - this.viewAngle = viewAngle; - } - - public MUTCDCode getMutcdCode() { - return mutcdCode; - } - - public void setMutcdCode(MUTCDCode mutcdCode) { - this.mutcdCode = mutcdCode; - } - - public MsgCRC getCrc() { - return crc; - } - - public void setCrc(MsgCRC crc) { - this.crc = crc; - } - RoadSignID() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java index b0ece2916..a1568b765 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class RoadwayCrownAngle extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java index fef0ff80d..02738fb21 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SSPindex extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java index 0a712a5fb..f9e6c41c5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Scale_B12 extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java index fbf188d3c..2a0ffc1ec 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java @@ -1,94 +1,95 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = SegmentAttributeLLSerializer.class) @JsonDeserialize(using = SegmentAttributeLLDeserializer.class) public enum SegmentAttributeLL implements Asn1Enumerated { - reserved(0, "reserved"), doNotBlock(1, "doNotBlock"), whiteLine(2, "whiteLine"), mergingLaneLeft(3, - "mergingLaneLeft"), mergingLaneRight(4, "mergingLaneRight"), curbOnLeft(5, "curbOnLeft"), curbOnRight(6, - "curbOnRight"), loadingzoneOnLeft(7, "loadingzoneOnLeft"), loadingzoneOnRight(8, - "loadingzoneOnRight"), turnOutPointOnLeft(9, "turnOutPointOnLeft"), turnOutPointOnRight(10, - "turnOutPointOnRight"), adjacentParkingOnLeft(11, - "adjacentParkingOnLeft"), adjacentParkingOnRight(12, - "adjacentParkingOnRight"), adjacentBikeLaneOnLeft(13, - "adjacentBikeLaneOnLeft"), adjacentBikeLaneOnRight(14, - "adjacentBikeLaneOnRight"), sharedBikeLane(15, - "sharedBikeLane"), bikeBoxInFront(16, - "bikeBoxInFront"), transitStopOnLeft( + RESERVED(0, "reserved"), DONOTBLOCK(1, "doNotBlock"), WHITELINE(2, "whiteLine"), MERGINGLANELEFT(3, + "mergingLaneLeft"), MERGINGLANERIGHT(4, "mergingLaneRight"), CURBONLEFT(5, "curbOnLeft"), CURBONRIGHT(6, + "curbOnRight"), LOADINGZONEONLEFT(7, "loadingzoneOnLeft"), LOADINGZONEONRIGHT(8, + "loadingzoneOnRight"), TURNOUTPOINTONLEFT(9, "turnOutPointOnLeft"), TURNOUTPOINTONRIGHT(10, + "turnOutPointOnRight"), ADJACENTPARKINGONLEFT(11, + "adjacentParkingOnLeft"), ADJACENTPARKINGONRIGHT(12, + "adjacentParkingOnRight"), ADJACENTBIKELANEONLEFT(13, + "adjacentBikeLaneOnLeft"), ADJACENTBIKELANEONRIGHT(14, + "adjacentBikeLaneOnRight"), SHAREDBIKELANE(15, + "sharedBikeLane"), BIKEBOXINFRONT(16, + "bikeBoxInFront"), TRANSITSTOPONLEFT( 17, - "transitStopOnLeft"), transitStopOnRight( + "transitStopOnLeft"), TRANSITSTOPONRIGHT( 18, - "transitStopOnRight"), transitStopInLane( + "transitStopOnRight"), TRANSITSTOPINLANE( 19, - "transitStopInLane"), sharedWithTrackedVehicle( + "transitStopInLane"), SHAREDWITHTRACKEDVEHICLE( 20, - "sharedWithTrackedVehicle"), safeIsland( + "sharedWithTrackedVehicle"), SAFEISLAND( 21, - "safeIsland"), lowCurbsPresent( + "safeIsland"), LOWCURBSPRESENT( 22, - "lowCurbsPresent"), rumbleStripPresent( + "lowCurbsPresent"), RUMBLESTRIPPRESENT( 23, - "rumbleStripPresent"), audibleSignalingPresent( + "rumbleStripPresent"), AUDIBLESIGNALINGPRESENT( 24, - "audibleSignalingPresent"), adaptiveTimingPresent( + "audibleSignalingPresent"), ADAPTIVETIMINGPRESENT( 25, - "adaptiveTimingPresent"), rfSignalRequestPresent( + "adaptiveTimingPresent"), RFSIGNALREQUESTPRESENT( 26, - "rfSignalRequestPresent"), partialCurbIntrusion( + "rfSignalRequestPresent"), PARTIALCURBINTRUSION( 27, - "partialCurbIntrusion"), taperToLeft( + "partialCurbIntrusion"), TAPERTOLEFT( 28, - "taperToLeft"), taperToRight( + "taperToLeft"), TAPERTORIGHT( 29, - "taperToRight"), taperToCenterLine( + "taperToRight"), TAPERTOCENTERLINE( 30, - "taperToCenterLine"), parallelParking( + "taperToCenterLine"), PARALLELPARKING( 31, - "parallelParking"), headInParking( + "parallelParking"), HEADINPARKING( 32, - "headInParking"), freeParking( + "headInParking"), FREEPARKING( 33, - "freeParking"), timeRestrictionsOnParking( + "freeParking"), TIMERESTRICTIONSONPARKING( 34, - "timeRestrictionsOnParking"), costToPark( + "timeRestrictionsOnParking"), COSTTOPARK( 35, - "costToPark"), midBlockCurbPresent( + "costToPark"), MIDBLOCKCURBPRESENT( 36, - "midBlockCurbPresent"), unEvenPavementPresent( + "midBlockCurbPresent"), UNEVENPAVEMENTPRESENT( 37, "unEvenPavementPresent"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java index b5820113e..dcad42c12 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SegmentAttributeLLDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java index 70e3a8055..dcc7cf380 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java index 13786839f..f17cb1d73 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SegmentAttributeLLSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java index db8bb5d45..18931898f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java @@ -1,94 +1,95 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = SegmentAttributeXYSerializer.class) @JsonDeserialize(using = SegmentAttributeXYDeserializer.class) public enum SegmentAttributeXY implements Asn1Enumerated { - reserved(0, "reserved"), doNotBlock(1, "doNotBlock"), whiteLine(2, "whiteLine"), mergingLaneLeft(3, - "mergingLaneLeft"), mergingLaneRight(4, "mergingLaneRight"), curbOnLeft(5, "curbOnLeft"), curbOnRight(6, - "curbOnRight"), loadingzoneOnLeft(7, "loadingzoneOnLeft"), loadingzoneOnRight(8, - "loadingzoneOnRight"), turnOutPointOnLeft(9, "turnOutPointOnLeft"), turnOutPointOnRight(10, - "turnOutPointOnRight"), adjacentParkingOnLeft(11, - "adjacentParkingOnLeft"), adjacentParkingOnRight(12, - "adjacentParkingOnRight"), adjacentBikeLaneOnLeft(13, - "adjacentBikeLaneOnLeft"), adjacentBikeLaneOnRight(14, - "adjacentBikeLaneOnRight"), sharedBikeLane(15, - "sharedBikeLane"), bikeBoxInFront(16, - "bikeBoxInFront"), transitStopOnLeft( + RESERVED(0, "reserved"), DONOTBLOCK(1, "doNotBlock"), WHITELINE(2, "whiteLine"), MERGINGLANELEFT(3, + "mergingLaneLeft"), MERGINGLANERIGHT(4, "mergingLaneRight"), CURBONLEFT(5, "curbOnLeft"), CURBONRIGHT(6, + "curbOnRight"), LOADINGZONEONLEFT(7, "loadingzoneOnLeft"), LOADINGZONEONRIGHT(8, + "loadingzoneOnRight"), TURNOUTPOINTONLEFT(9, "turnOutPointOnLeft"), TURNOUTPOINTONRIGHT(10, + "turnOutPointOnRight"), ADJACENTPARKINGONLEFT(11, + "adjacentParkingOnLeft"), ADJACENTPARKINGONRIGHT(12, + "adjacentParkingOnRight"), ADJACENTBIKELANEONLEFT(13, + "adjacentBikeLaneOnLeft"), ADJACENTBIKELANEONRIGHT(14, + "adjacentBikeLaneOnRight"), SHAREDBIKELANE(15, + "sharedBikeLane"), BIKEBOXINFRONT(16, + "bikeBoxInFront"), TRANSITSTOPONLEFT( 17, - "transitStopOnLeft"), transitStopOnRight( + "transitStopOnLeft"), TRANSITSTOPONRIGHT( 18, - "transitStopOnRight"), transitStopInLane( + "transitStopOnRight"), TRANSITSTOPINLANE( 19, - "transitStopInLane"), sharedWithTrackedVehicle( + "transitStopInLane"), SHAREDWITHTRACKEDVEHICLE( 20, - "sharedWithTrackedVehicle"), safeIsland( + "sharedWithTrackedVehicle"), SAFEISLAND( 21, - "safeIsland"), lowCurbsPresent( + "safeIsland"), LOWCURBSPRESENT( 22, - "lowCurbsPresent"), rumbleStripPresent( + "lowCurbsPresent"), RUMBLESTRIPPRESENT( 23, - "rumbleStripPresent"), audibleSignalingPresent( + "rumbleStripPresent"), AUDIBLESIGNALINGPRESENT( 24, - "audibleSignalingPresent"), adaptiveTimingPresent( + "audibleSignalingPresent"), ADAPTIVETIMINGPRESENT( 25, - "adaptiveTimingPresent"), rfSignalRequestPresent( + "adaptiveTimingPresent"), RFSIGNALREQUESTPRESENT( 26, - "rfSignalRequestPresent"), partialCurbIntrusion( + "rfSignalRequestPresent"), PARTIALCURBINTRUSION( 27, - "partialCurbIntrusion"), taperToLeft( + "partialCurbIntrusion"), TAPERTOLEFT( 28, - "taperToLeft"), taperToRight( + "taperToLeft"), TAPERTORIGHT( 29, - "taperToRight"), taperToCenterLine( + "taperToRight"), TAPERTOCENTERLINE( 30, - "taperToCenterLine"), parallelParking( + "taperToCenterLine"), PARALLELPARKING( 31, - "parallelParking"), headInParking( + "parallelParking"), HEADINPARKING( 32, - "headInParking"), freeParking( + "headInParking"), FREEPARKING( 33, - "freeParking"), timeRestrictionsOnParking( + "freeParking"), TIMERESTRICTIONSONPARKING( 34, - "timeRestrictionsOnParking"), costToPark( + "timeRestrictionsOnParking"), COSTTOPARK( 35, - "costToPark"), midBlockCurbPresent( + "costToPark"), MIDBLOCKCURBPRESENT( 36, - "midBlockCurbPresent"), unEvenPavementPresent( + "midBlockCurbPresent"), UNEVENPAVEMENTPRESENT( 37, "unEvenPavementPresent"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java index d576fd8fc..fc694eea5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SegmentAttributeXYDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java index ad4328245..d128cf679 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java @@ -7,19 +7,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java index 799bf39ee..6fe24c6aa 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SegmentAttributeXYSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java index 40a5e653a..dae1fd519 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java @@ -4,28 +4,39 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class ShapePointSet extends Asn1Sequence { @Asn1Property(tag = 0, optional = true) @@ -38,38 +49,6 @@ public class ShapePointSet extends Asn1Sequence { @Asn1Property(tag = 3) private NodeListXY nodeList; - public Position3D getAnchor() { - return anchor; - } - - public void setAnchor(Position3D anchor) { - this.anchor = anchor; - } - - public LaneWidth getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(LaneWidth laneWidth) { - this.laneWidth = laneWidth; - } - - public DirectionOfUse getDirectionality() { - return directionality; - } - - public void setDirectionality(DirectionOfUse directionality) { - this.directionality = directionality; - } - - public NodeListXY getNodeList() { - return nodeList; - } - - public void setNodeList(NodeListXY nodeList) { - this.nodeList = nodeList; - } - ShapePointSet() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java index ff7768c97..b74fbd134 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SignPrority extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java index 6c571a6a1..5a4c2fc93 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java index c59418f0f..866f454d4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java index badf6e86a..623c1c48d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java @@ -9,33 +9,46 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class SpeedLimitSequence extends Asn1Sequence { @Asn1Property(tag = 0) private ItemChoice item; + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -48,36 +61,12 @@ public static class ItemChoice extends Asn1Choice { super(false); } - public ITIScodes getItis() { - return itis; - } - - public void setItis(ITIScodes itis) { - this.itis = itis; - } - - public ITIStextPhrase getText() { - return text; - } - - public void setText(ITIStextPhrase text) { - this.text = text; - } - @Override protected List> listTypes() { return null; } } - public ItemChoice getItem() { - return item; - } - - public void setItem(ItemChoice item) { - this.item = item; - } - SpeedLimitSequence() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java index a1d936415..add530a57 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java @@ -1,50 +1,51 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = SpeedLimitTypeSerializer.class) @JsonDeserialize(using = SpeedLimitTypeDeserializer.class) public enum SpeedLimitType implements Asn1Enumerated { - unknown(0, "unknown"), maxSpeedInSchoolZone(1, "maxSpeedInSchoolZone"), maxSpeedInSchoolZoneWhenChildrenArePresent( - 2, "maxSpeedInSchoolZoneWhenChildrenArePresent"), maxSpeedInConstructionZone(3, - "maxSpeedInConstructionZone"), vehicleMinSpeed(4, "vehicleMinSpeed"), vehicleMaxSpeed(5, - "vehicleMaxSpeed"), vehicleNightMaxSpeed(6, "vehicleNightMaxSpeed"), truckMinSpeed(7, - "truckMinSpeed"), truckMaxSpeed(8, "truckMaxSpeed"), truckNightMaxSpeed(9, - "truckNightMaxSpeed"), vehiclesWithTrailersMinSpeed(10, - "vehiclesWithTrailersMinSpeed"), vehiclesWithTrailersMaxSpeed(11, - "vehiclesWithTrailersMaxSpeed"), vehiclesWithTrailersNightMaxSpeed( + UNKNOWN(0, "unknown"), MAXSPEEDINSCHOOLZONE(1, "maxSpeedInSchoolZone"), MAXSPEEDINSCHOOLZONEWHENCHILDRENAREPRESENT( + 2, "maxSpeedInSchoolZoneWhenChildrenArePresent"), MAXSPEEDINCONSTRUCTIONZONE(3, + "maxSpeedInConstructionZone"), VEHICLEMINSPEED(4, "vehicleMinSpeed"), VEHICLEMAXSPEED(5, + "vehicleMaxSpeed"), VEHICLENIGHTMAXSPEED(6, "vehicleNightMaxSpeed"), TRUCKMINSPEED(7, + "truckMinSpeed"), TRUCKMAXSPEED(8, "truckMaxSpeed"), TRUCKNIGHTMAXSPEED(9, + "truckNightMaxSpeed"), VEHICLESWITHTRAILERSMINSPEED(10, + "vehiclesWithTrailersMinSpeed"), VEHICLESWITHTRAILERSMAXSPEED(11, + "vehiclesWithTrailersMaxSpeed"), VEHICLESWITHTRAILERSNIGHTMAXSPEED( 12, "vehiclesWithTrailersNightMaxSpeed"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java index a5eff73e4..be7db2377 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SpeedLimitTypeDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java index 6f9482bf0..0163b370d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class SpeedLimitTypeSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java index cfe03e8ef..fcd68f442 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; @@ -16,25 +18,38 @@ import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; +/* + * EDITED -> notUsed, notUsed1, notUsed2, notUsed3 fields. + */ + /** - * EDITED: Fixed "notUsed" properties. - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ * + ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at * - *
- * J2735_201603DA.ASN
- * 
+ * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class TravelerDataFrame extends Asn1Sequence { @Asn1Property(tag = 0) @@ -72,22 +87,8 @@ public class TravelerDataFrame extends Asn1Sequence { @Asn1Property(tag = 12, optional = true) private URL_Short url; - public SSPindex getNotUsed() { - return notUsed; - } - - public void setNotUsed(SSPindex notUsed) { - this.notUsed = notUsed; - } - - public TravelerInfoType getFrameType() { - return frameType; - } - - public void setFrameType(TravelerInfoType frameType) { - this.frameType = frameType; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class MsgIdChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -99,76 +100,12 @@ public static class MsgIdChoice extends Asn1Choice { super(false); } - public FurtherInfoID getFurtherInfoID() { - return furtherInfoID; - } - - public void setFurtherInfoID(FurtherInfoID furtherInfoID) { - this.furtherInfoID = furtherInfoID; - } - - public RoadSignID getRoadSignID() { - return roadSignID; - } - - public void setRoadSignID(RoadSignID roadSignID) { - this.roadSignID = roadSignID; - } - @Override protected List> listTypes() { return null; } } - public MsgIdChoice getMsgId() { - return msgId; - } - - public void setMsgId(MsgIdChoice msgId) { - this.msgId = msgId; - } - - public DYear getStartYear() { - return startYear; - } - - public void setStartYear(DYear startYear) { - this.startYear = startYear; - } - - public MinuteOfTheYear getStartTime() { - return startTime; - } - - public void setStartTime(MinuteOfTheYear startTime) { - this.startTime = startTime; - } - - public MinutesDuration getDuratonTime() { - return duratonTime; - } - - public void setDuratonTime(MinutesDuration duratonTime) { - this.duratonTime = duratonTime; - } - - public SignPrority getPriority() { - return priority; - } - - public void setPriority(SignPrority priority) { - this.priority = priority; - } - - public SSPindex getNotUsed1() { - return notUsed1; - } - - public void setNotUsed1(SSPindex notUsed1) { - this.notUsed1 = notUsed1; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegions extends Asn1SequenceOf { SequenceOfRegions() { @@ -176,30 +113,8 @@ public static class SequenceOfRegions extends Asn1SequenceOf { } } - public SequenceOfRegions getRegions() { - return regions; - } - - public void setRegions(SequenceOfRegions regions) { - this.regions = regions; - } - - public SSPindex getNotUsed2() { - return notUsed2; - } - - public void setNotUsed2(SSPindex notUsed2) { - this.notUsed2 = notUsed2; - } - - public SSPindex getNotUsed3() { - return notUsed3; - } - - public void setNotUsed3(SSPindex notUsed3) { - this.notUsed3 = notUsed3; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ContentChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -227,68 +142,12 @@ public static class ContentChoice extends Asn1Choice { super(false); } - public ITIScodesAndText getAdvisory() { - return advisory; - } - - public void setAdvisory(ITIScodesAndText advisory) { - this.advisory = advisory; - } - - public WorkZone getWorkZone() { - return workZone; - } - - public void setWorkZone(WorkZone workZone) { - this.workZone = workZone; - } - - public GenericSignage getGenericSign() { - return genericSign; - } - - public void setGenericSign(GenericSignage genericSign) { - this.genericSign = genericSign; - } - - public SpeedLimit getSpeedLimit() { - return speedLimit; - } - - public void setSpeedLimit(SpeedLimit speedLimit) { - this.speedLimit = speedLimit; - } - - public ExitService getExitService() { - return exitService; - } - - public void setExitService(ExitService exitService) { - this.exitService = exitService; - } - @Override protected List> listTypes() { return null; } } - public ContentChoice getContent() { - return content; - } - - public void setContent(ContentChoice content) { - this.content = content; - } - - public URL_Short getUrl() { - return url; - } - - public void setUrl(URL_Short url) { - this.url = url; - } - TravelerDataFrame() { super(true); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak new file mode 100644 index 000000000..cfe03e8ef --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak @@ -0,0 +1,355 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodesAndText; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * EDITED: Fixed "notUsed" properties. + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TravelerDataFrame extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed; + @Asn1Property(tag = 1) + private TravelerInfoType frameType; + @Asn1Property(tag = 2) + private MsgIdChoice msgId; + @Asn1Property(tag = 3, optional = true) + @JsonDeserialize(using = DYear.DYearDeserializer.class) + private DYear startYear; + @Asn1Property(tag = 4) + @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + private MinuteOfTheYear startTime; + @Asn1Property(tag = 5) + @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) + private MinutesDuration duratonTime; + @Asn1Property(tag = 6) + @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) + private SignPrority priority; + @Asn1Property(tag = 7) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed1; + @Asn1Property(tag = 8) + private SequenceOfRegions regions; + @Asn1Property(tag = 9) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed2; + @Asn1Property(tag = 10) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed3; + @Asn1Property(tag = 11) + private ContentChoice content; + @Asn1Property(tag = 12, optional = true) + private URL_Short url; + + public SSPindex getNotUsed() { + return notUsed; + } + + public void setNotUsed(SSPindex notUsed) { + this.notUsed = notUsed; + } + + public TravelerInfoType getFrameType() { + return frameType; + } + + public void setFrameType(TravelerInfoType frameType) { + this.frameType = frameType; + } + + @JsonInclude(Include.NON_NULL) + public static class MsgIdChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private FurtherInfoID furtherInfoID; + @Asn1Property(tag = 1) + private RoadSignID roadSignID; + + MsgIdChoice() { + super(false); + } + + public FurtherInfoID getFurtherInfoID() { + return furtherInfoID; + } + + public void setFurtherInfoID(FurtherInfoID furtherInfoID) { + this.furtherInfoID = furtherInfoID; + } + + public RoadSignID getRoadSignID() { + return roadSignID; + } + + public void setRoadSignID(RoadSignID roadSignID) { + this.roadSignID = roadSignID; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public MsgIdChoice getMsgId() { + return msgId; + } + + public void setMsgId(MsgIdChoice msgId) { + this.msgId = msgId; + } + + public DYear getStartYear() { + return startYear; + } + + public void setStartYear(DYear startYear) { + this.startYear = startYear; + } + + public MinuteOfTheYear getStartTime() { + return startTime; + } + + public void setStartTime(MinuteOfTheYear startTime) { + this.startTime = startTime; + } + + public MinutesDuration getDuratonTime() { + return duratonTime; + } + + public void setDuratonTime(MinutesDuration duratonTime) { + this.duratonTime = duratonTime; + } + + public SignPrority getPriority() { + return priority; + } + + public void setPriority(SignPrority priority) { + this.priority = priority; + } + + public SSPindex getNotUsed1() { + return notUsed1; + } + + public void setNotUsed1(SSPindex notUsed1) { + this.notUsed1 = notUsed1; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegions extends Asn1SequenceOf { + SequenceOfRegions() { + super(GeographicalPath.class, 1L, 16L); + } + } + + public SequenceOfRegions getRegions() { + return regions; + } + + public void setRegions(SequenceOfRegions regions) { + this.regions = regions; + } + + public SSPindex getNotUsed2() { + return notUsed2; + } + + public void setNotUsed2(SSPindex notUsed2) { + this.notUsed2 = notUsed2; + } + + public SSPindex getNotUsed3() { + return notUsed3; + } + + public void setNotUsed3(SSPindex notUsed3) { + this.notUsed3 = notUsed3; + } + + @JsonInclude(Include.NON_NULL) + public static class ContentChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = AdvisoryDeserializer.class) + @JsonSerialize(using = AdvisorySerializer.class) + private ITIScodesAndText advisory; + @Asn1Property(tag = 1) + @JsonDeserialize(using = WorkZoneDeserializer.class) + @JsonSerialize(using = WorkZoneSerializer.class) + private WorkZone workZone; + @Asn1Property(tag = 2) + @JsonDeserialize(using = GenericSignDeserializer.class) + @JsonSerialize(using = GenericSignSerializer.class) + private GenericSignage genericSign; + @Asn1Property(tag = 3) + @JsonDeserialize(using = SpeedLimitDeserializer.class) + @JsonSerialize(using = SpeedLimitSerializer.class) + private SpeedLimit speedLimit; + @Asn1Property(tag = 4) + @JsonDeserialize(using = ExitServiceDeserializer.class) + @JsonSerialize(using = ExitServiceSerializer.class) + private ExitService exitService; + + ContentChoice() { + super(false); + } + + public ITIScodesAndText getAdvisory() { + return advisory; + } + + public void setAdvisory(ITIScodesAndText advisory) { + this.advisory = advisory; + } + + public WorkZone getWorkZone() { + return workZone; + } + + public void setWorkZone(WorkZone workZone) { + this.workZone = workZone; + } + + public GenericSignage getGenericSign() { + return genericSign; + } + + public void setGenericSign(GenericSignage genericSign) { + this.genericSign = genericSign; + } + + public SpeedLimit getSpeedLimit() { + return speedLimit; + } + + public void setSpeedLimit(SpeedLimit speedLimit) { + this.speedLimit = speedLimit; + } + + public ExitService getExitService() { + return exitService; + } + + public void setExitService(ExitService exitService) { + this.exitService = exitService; + } + + @Override + protected List> listTypes() { + return null; + } + } + + public ContentChoice getContent() { + return content; + } + + public void setContent(ContentChoice content) { + this.content = content; + } + + public URL_Short getUrl() { + return url; + } + + public void setUrl(URL_Short url) { + this.url = url; + } + + TravelerDataFrame() { + super(true); + } + + public static class AdvisoryDeserializer extends NestedSequenceOfDeserializer { + public AdvisoryDeserializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class AdvisorySerializer extends NestedSequenceOfSerializer { + public AdvisorySerializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class WorkZoneDeserializer extends NestedSequenceOfDeserializer { + public WorkZoneDeserializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class WorkZoneSerializer extends NestedSequenceOfSerializer { + public WorkZoneSerializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class GenericSignDeserializer extends NestedSequenceOfDeserializer { + public GenericSignDeserializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class GenericSignSerializer extends NestedSequenceOfSerializer { + public GenericSignSerializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class SpeedLimitDeserializer extends NestedSequenceOfDeserializer { + public SpeedLimitDeserializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class SpeedLimitSerializer extends NestedSequenceOfSerializer { + public SpeedLimitSerializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class ExitServiceDeserializer extends NestedSequenceOfDeserializer { + public ExitServiceDeserializer() { + super(ExitService.class, "SEQUENCE"); + } + } + + public static class ExitServiceSerializer extends NestedSequenceOfSerializer { + public ExitServiceSerializer() { + super(ExitService.class, "SEQUENCE"); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java index 4b5e810be..d1d89e199 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java index 206999c8c..323267c8f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java @@ -1,43 +1,44 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; +import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ +@Getter @JsonSerialize(using = TravelerInfoTypeSerializer.class) @JsonDeserialize(using = TravelerInfoTypeDeserializer.class) public enum TravelerInfoType implements Asn1Enumerated { - unknown(0, "unknown"), advisory(1, "advisory"), roadSignage(2, "roadSignage"), commercialSignage(3, + UNKNOWN(0, "unknown"), ADVISORY(1, "advisory"), ROADSIGNAGE(2, "roadSignage"), COMMERCIALSIGNAGE(3, "commercialSignage"); private final int index; private final String name; - public int getIndex() { - return index; - } - - public String getName() { - return name; - } - public boolean hasExtensionMarker() { return false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java index 7062d0455..15cf06ae1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class TravelerInfoTypeDeserializer extends EnumeratedDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java index f17d6c568..23c31bc60 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java @@ -4,19 +4,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class TravelerInfoTypeSerializer extends EnumeratedSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java index 804a14f63..6a7cc99eb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java @@ -1,36 +1,51 @@ package us.dot.its.jpo.ode.plugin.j2735.DSRC; -//import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +/* + * EDITED - Changed base class to Asn1Object + */ + /** - * EDITED: Changed base class to Asn1Object. - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ * EDITED - Change base class to Asn1Object + ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class TravelerInformation extends Asn1Object { @Asn1Property(tag = 0) @@ -50,62 +65,14 @@ public class TravelerInformation extends Asn1Object { @Asn1Property(tag = 5, optional = true) private SequenceOfRegional regional; - public MsgCount getMsgCnt() { - return msgCnt; - } - - public void setMsgCnt(MsgCount msgCnt) { - this.msgCnt = msgCnt; - } - - public MinuteOfTheYear getTimeStamp() { - return timeStamp; - } - - public void setTimeStamp(MinuteOfTheYear timeStamp) { - this.timeStamp = timeStamp; - } - - public UniqueMSGID getPacketID() { - return packetID; - } - - public void setPacketID(UniqueMSGID packetID) { - this.packetID = packetID; - } - - public URL_Base getUrlB() { - return urlB; - } - - public void setUrlB(URL_Base urlB) { - this.urlB = urlB; - } - - public TravelerDataFrameList getDataFrames() { - return dataFrames; - } - - public void setDataFrames(TravelerDataFrameList dataFrames) { - this.dataFrames = dataFrames; - } - @JsonInclude(Include.NON_NULL) public static class SequenceOfRegional extends Asn1SequenceOf { SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation.class, 1L, 4L); + super(Reg_TravelerInformation.class, 1L, 4L); } } - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - - // TravelerInformation() { - // super(true); - // } +// TravelerInformation() { +// super(true); +// } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak new file mode 100644 index 000000000..804a14f63 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak @@ -0,0 +1,111 @@ +package us.dot.its.jpo.ode.plugin.j2735.DSRC; + +//import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; + +/** + * EDITED: Changed base class to Asn1Object. + *

+ * This source code was generated by a tool. Manual edits are futile. + *

+ *

+ * asn1jvm v1.0-SNAPSHOT + *

+ *

+ * ASN.1 source files: + *

+ * + *
+ * J2735_201603DA.ASN
+ * 
+ * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class TravelerInformation extends Asn1Object { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = MsgCount.MsgCountDeserializer.class) + private MsgCount msgCnt; + @Asn1Property(tag = 1, optional = true) + @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + private MinuteOfTheYear timeStamp; + @Asn1Property(tag = 2, optional = true) + private UniqueMSGID packetID; + @Asn1Property(tag = 3, optional = true) + private URL_Base urlB; + @Asn1Property(tag = 4) + @JacksonXmlElementWrapper(localName = "dataFrames") + @JacksonXmlProperty(localName = "TravelerDataFrame") + private TravelerDataFrameList dataFrames; + @Asn1Property(tag = 5, optional = true) + private SequenceOfRegional regional; + + public MsgCount getMsgCnt() { + return msgCnt; + } + + public void setMsgCnt(MsgCount msgCnt) { + this.msgCnt = msgCnt; + } + + public MinuteOfTheYear getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(MinuteOfTheYear timeStamp) { + this.timeStamp = timeStamp; + } + + public UniqueMSGID getPacketID() { + return packetID; + } + + public void setPacketID(UniqueMSGID packetID) { + this.packetID = packetID; + } + + public URL_Base getUrlB() { + return urlB; + } + + public void setUrlB(URL_Base urlB) { + this.urlB = urlB; + } + + public TravelerDataFrameList getDataFrames() { + return dataFrames; + } + + public void setDataFrames(TravelerDataFrameList dataFrames) { + this.dataFrames = dataFrames; + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation.class, 1L, 4L); + } + } + + public SequenceOfRegional getRegional() { + return regional; + } + + public void setRegional(SequenceOfRegional regional) { + this.regional = regional; + } + + // TravelerInformation() { + // super(true); + // } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java index a93a91c93..62909df7a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class URL_Base extends IA5String { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java index f95536afa..54e2c0329 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class URL_Short extends IA5String { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java index a700e956b..433cba1e7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class UniqueMSGID extends Asn1OctetString { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java index b6d3bc1c1..2772b975d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; @@ -12,23 +14,32 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class ValidRegion extends Asn1Sequence { @Asn1Property(tag = 0) @@ -38,22 +49,8 @@ public class ValidRegion extends Asn1Sequence { @Asn1Property(tag = 2) private AreaChoice area; - public HeadingSlice getDirection() { - return direction; - } - - public void setDirection(HeadingSlice direction) { - this.direction = direction; - } - - public Extent getExtent() { - return extent; - } - - public void setExtent(Extent extent) { - this.extent = extent; - } - + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class AreaChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -67,44 +64,12 @@ public static class AreaChoice extends Asn1Choice { super(false); } - public ShapePointSet getShapePointSet() { - return shapePointSet; - } - - public void setShapePointSet(ShapePointSet shapePointSet) { - this.shapePointSet = shapePointSet; - } - - public Circle getCircle() { - return circle; - } - - public void setCircle(Circle circle) { - this.circle = circle; - } - - public RegionPointSet getRegionPointSet() { - return regionPointSet; - } - - public void setRegionPointSet(RegionPointSet regionPointSet) { - this.regionPointSet = regionPointSet; - } - @Override protected List> listTypes() { return null; } } - public AreaChoice getArea() { - return area; - } - - public void setArea(AreaChoice area) { - this.area = area; - } - ValidRegion() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java index 959be197f..903873564 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Velocity extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java index 78268ac2b..01059af20 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java index 4d7733b38..697950888 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java @@ -9,33 +9,46 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class WorkZoneSequence extends Asn1Sequence { @Asn1Property(tag = 0) private ItemChoice item; + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -48,36 +61,12 @@ public static class ItemChoice extends Asn1Choice { super(false); } - public ITIScodes getItis() { - return itis; - } - - public void setItis(ITIScodes itis) { - this.itis = itis; - } - - public ITIStextPhrase getText() { - return text; - } - - public void setText(ITIStextPhrase text) { - this.text = text; - } - @Override protected List> listTypes() { return null; } } - public ItemChoice getItem() { - return item; - } - - public void setItem(ItemChoice item) { - this.item = item; - } - WorkZoneSequence() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java index a970950fc..988311b91 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class Zoom extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java index 5b6079e51..2e43436b9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class ITIScodes extends Asn1Integer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java index 18c2874b2..ee5bf9b34 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java index 5a8b4102f..8170f1ff3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java @@ -8,33 +8,46 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import lombok.Getter; +import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter public class ITIScodesAndTextSequence extends Asn1Sequence { @Asn1Property(tag = 0) private ItemChoice item; + @Getter + @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { @Asn1Property(tag = 0) @@ -47,36 +60,12 @@ public static class ItemChoice extends Asn1Choice { super(false); } - public ITIScodes getItis() { - return itis; - } - - public void setItis(ITIScodes itis) { - this.itis = itis; - } - - public ITIStext getText() { - return text; - } - - public void setText(ITIStext text) { - this.text = text; - } - @Override protected List> listTypes() { return null; } } - public ItemChoice getItem() { - return item; - } - - public void setItem(ItemChoice item) { - this.item = item; - } - ITIScodesAndTextSequence() { super(false); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java index f517967ae..213baae24 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java @@ -5,19 +5,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ public class ITIStext extends IA5String { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java index f979efaa4..a9fa04d1a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java index c31cb1a3d..6ef13814f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java index 7e1c121f6..00a482bb2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java index 484f60051..1b64c7495 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java @@ -9,30 +9,38 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") @JsonSubTypes({ - @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, name = "2")}) + @JsonSubTypes.Type(value = LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, name = "2")}) @Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { - @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, intId = 2)}) + @Asn1ParameterizedTypes.Type(value = LaneDataAttribute_addGrpBReg_LaneDataAttribute.class, intId = 2)}) abstract public class Reg_LaneDataAttribute extends RegionalExtension { public Reg_LaneDataAttribute(int id, String name) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java index e3cb75c81..07e386bc8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java index bcc1df192..82bc64922 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java index ea683e0ee..9cccb2a02 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java index 2ac717f5e..86074ae06 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java @@ -9,30 +9,38 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") @JsonSubTypes({ - @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, name = "2")}) + @JsonSubTypes.Type(value = NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, name = "2")}) @Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { - @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, intId = 2)}) + @Asn1ParameterizedTypes.Type(value = NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.class, intId = 2)}) abstract public class Reg_NodeOffsetPointXY extends RegionalExtension { public Reg_NodeOffsetPointXY(int id, String name) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java index 59e04379c..0c785e5be 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java @@ -9,31 +9,40 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D; /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") -@JsonSubTypes({@JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D.class, name = "2"), - @JsonSubTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D.class, name = "3")}) +@JsonSubTypes({@JsonSubTypes.Type(value = Position3D_addGrpBReg_Position3D.class, name = "2"), + @JsonSubTypes.Type(value = Position3D_addGrpCReg_Position3D.class, name = "3")}) @Asn1ParameterizedTypes(idProperty = "regionId", idType = IdType.INTEGER, valueProperty = "regExtValue", value = { - @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D.class, intId = 2), - @Asn1ParameterizedTypes.Type(value = us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D.class, intId = 3)}) + @Asn1ParameterizedTypes.Type(value = Position3D_addGrpBReg_Position3D.class, intId = 2), + @Asn1ParameterizedTypes.Type(value = Position3D_addGrpCReg_Position3D.class, intId = 3)}) abstract public class Reg_Position3D extends RegionalExtension { public Reg_Position3D(int id, String name) { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java index 79478a6ca..d2ba1b9da 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java @@ -6,19 +6,26 @@ /** * - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

+ ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT * - *
- * J2735_201603DA.ASN
- * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** * */ @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java deleted file mode 100644 index 2ee29d0fc..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Field.java +++ /dev/null @@ -1,5 +0,0 @@ -//package asn2pojo.runtime.types; -// -//public record Asn1Field(String name, Asn1Type value, boolean optional, int tag) { -// -//} From f2239886f3912014c12435b910aa33f3dc25b06e Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:58:38 -0700 Subject: [PATCH 124/264] Use 2020/2024 modules as package names. Package names lower case. --- .../dot/its/jpo/ode/model/OdeTimPayload.java | 2 +- .../j2735/DSRC/TravelerDataFrame.java_bak | 355 ------------------ .../j2735/DSRC/TravelerInformation.java_bak | 111 ------ .../{AddGrpB => addgrpb}/DegreesLat.java | 2 +- .../{AddGrpB => addgrpb}/DegreesLong.java | 2 +- .../j2735/{AddGrpB => addgrpb}/Elevation.java | 2 +- .../LaneDataAttribute_addGrpB.java | 2 +- ...ttribute_addGrpBReg_LaneDataAttribute.java | 4 +- ...eg_LaneDataAttributeValueDeserializer.java | 2 +- ...BReg_LaneDataAttributeValueSerializer.java | 2 +- .../{AddGrpB => addgrpb}/LatitudeDMS.java | 2 +- .../{AddGrpB => addgrpb}/LatitudeDMS2.java | 2 +- .../{AddGrpB => addgrpb}/LongitudeDMS.java | 2 +- .../{AddGrpB => addgrpb}/LongitudeDMS2.java | 2 +- .../{AddGrpB => addgrpb}/MinutesAngle.java | 2 +- .../NodeOffsetPointXY_addGrpB.java | 2 +- ...tPointXY_addGrpBReg_NodeOffsetPointXY.java | 4 +- ...eg_NodeOffsetPointXYValueDeserializer.java | 2 +- ...BReg_NodeOffsetPointXYValueSerializer.java | 2 +- .../{AddGrpB => addgrpb}/Node_LLdms_48b.java | 2 +- .../{AddGrpB => addgrpb}/Node_LLdms_80b.java | 2 +- .../Position3D_addGrpB.java | 2 +- .../Position3D_addGrpBReg_Position3D.java | 4 +- ...ddGrpBReg_Position3DValueDeserializer.java | 2 +- ..._addGrpBReg_Position3DValueSerializer.java | 2 +- .../{AddGrpB => addgrpb}/SecondsAngle.java | 2 +- .../j2735/{AddGrpC => addgrpc}/Altitude.java | 2 +- .../AltitudeConfidence.java | 2 +- .../AltitudeConfidenceDeserializer.java | 2 +- .../AltitudeConfidenceSerializer.java | 2 +- .../{AddGrpC => addgrpc}/AltitudeValue.java | 2 +- .../Position3D_addGrpC.java | 2 +- .../Position3D_addGrpCReg_Position3D.java | 4 +- ...ddGrpCReg_Position3DValueDeserializer.java | 2 +- ..._addGrpCReg_Position3DValueSerializer.java | 2 +- .../plugin/j2735/{DSRC => common}/Angle.java | 2 +- .../j2735/{DSRC => common}/ComputedLane.java | 4 +- .../plugin/j2735/{DSRC => common}/DYear.java | 2 +- .../j2735/{DSRC => common}/DeltaAngle.java | 2 +- .../{DSRC => common}/DescriptiveName.java | 2 +- .../{DSRC => common}/DrivenLineOffsetLg.java | 2 +- .../{DSRC => common}/DrivenLineOffsetSm.java | 2 +- .../j2735/{DSRC => common}/Elevation.java | 2 +- .../plugin/j2735/{DSRC => common}/Extent.java | 2 +- .../{DSRC => common}/ExtentDeserializer.java | 2 +- .../{DSRC => common}/ExtentSerializer.java | 2 +- .../j2735/{DSRC => common}/FurtherInfoID.java | 2 +- .../j2735/{DSRC => common}/HeadingSlice.java | 2 +- .../HeadingSliceDeserializer.java | 2 +- .../{DSRC => common}/LaneDataAttribute.java | 4 +- .../LaneDataAttributeList.java | 2 +- .../plugin/j2735/{DSRC => common}/LaneID.java | 2 +- .../j2735/{DSRC => common}/LaneWidth.java | 2 +- .../j2735/{DSRC => common}/Latitude.java | 2 +- .../j2735/{DSRC => common}/Longitude.java | 2 +- .../MergeDivergeNodeAngle.java | 2 +- .../{DSRC => common}/MinuteOfTheYear.java | 2 +- .../j2735/{DSRC => common}/MsgCount.java | 2 +- .../{DSRC => common}/NodeAttributeSetXY.java | 4 +- .../{DSRC => common}/NodeAttributeXY.java | 2 +- .../NodeAttributeXYDeserializer.java | 2 +- .../{DSRC => common}/NodeAttributeXYList.java | 2 +- .../NodeAttributeXYSerializer.java | 2 +- .../j2735/{DSRC => common}/NodeListXY.java | 2 +- .../{DSRC => common}/NodeOffsetPointXY.java | 4 +- .../j2735/{DSRC => common}/NodeSetXY.java | 2 +- .../plugin/j2735/{DSRC => common}/NodeXY.java | 2 +- .../j2735/{DSRC => common}/Node_LLmD_64b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_20b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_22b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_24b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_26b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_28b.java | 2 +- .../j2735/{DSRC => common}/Node_XY_32b.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B12.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B14.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B16.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B18.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B22.java | 2 +- .../j2735/{DSRC => common}/OffsetLL_B24.java | 2 +- .../j2735/{DSRC => common}/Offset_B10.java | 2 +- .../j2735/{DSRC => common}/Offset_B11.java | 2 +- .../j2735/{DSRC => common}/Offset_B12.java | 2 +- .../j2735/{DSRC => common}/Offset_B13.java | 2 +- .../j2735/{DSRC => common}/Offset_B14.java | 2 +- .../j2735/{DSRC => common}/Offset_B16.java | 2 +- .../j2735/{DSRC => common}/Position3D.java | 4 +- .../j2735/{DSRC => common}/RegionId.java | 2 +- .../{DSRC => common}/RegionalExtension.java | 2 +- .../RegulatorySpeedLimit.java | 2 +- .../{DSRC => common}/RoadRegulatorID.java | 2 +- .../j2735/{DSRC => common}/RoadSegmentID.java | 2 +- .../RoadSegmentReferenceID.java | 2 +- .../{DSRC => common}/RoadwayCrownAngle.java | 2 +- .../j2735/{DSRC => common}/SSPindex.java | 2 +- .../j2735/{DSRC => common}/Scale_B12.java | 2 +- .../{DSRC => common}/SegmentAttributeXY.java | 2 +- .../SegmentAttributeXYDeserializer.java | 2 +- .../SegmentAttributeXYList.java | 2 +- .../SegmentAttributeXYSerializer.java | 2 +- .../{DSRC => common}/SpeedLimitList.java | 2 +- .../{DSRC => common}/SpeedLimitType.java | 2 +- .../SpeedLimitTypeDeserializer.java | 2 +- .../SpeedLimitTypeSerializer.java | 2 +- .../j2735/{DSRC => common}/Velocity.java | 2 +- .../j2735/{ITIS => itis}/ITIScodes.java | 2 +- .../{ITIS => itis}/ITIScodesAndText.java | 2 +- .../ITIScodesAndTextSequence.java | 2 +- .../plugin/j2735/{ITIS => itis}/ITIStext.java | 2 +- .../{REGION => region}/Reg_ComputedLane.java | 4 +- .../Reg_GeographicalPath.java | 4 +- .../Reg_GeometricProjection.java | 4 +- .../Reg_LaneDataAttribute.java | 6 +- .../Reg_NodeAttributeSetLL.java | 4 +- .../Reg_NodeAttributeSetXY.java | 4 +- .../Reg_NodeOffsetPointLL.java | 4 +- .../Reg_NodeOffsetPointXY.java | 6 +- .../{REGION => region}/Reg_Position3D.java | 8 +- .../Reg_TravelerInformation.java | 4 +- .../{DSRC => travelerinformation}/Circle.java | 3 +- .../DirectionOfUse.java | 2 +- .../DirectionOfUseDeserializer.java | 2 +- .../DirectionOfUseSerializer.java | 2 +- .../DistanceUnits.java | 2 +- .../DistanceUnitsDeserializer.java | 2 +- .../DistanceUnitsSerializer.java | 2 +- .../ExitService.java | 2 +- .../ExitServiceSequence.java | 4 +- .../GenericSignage.java | 2 +- .../GenericSignageSequence.java | 4 +- .../GeographicalPath.java | 5 +- .../GeometricProjection.java | 7 +- .../ITIStextPhrase.java | 2 +- .../MUTCDCode.java | 2 +- .../MUTCDCodeDeserializer.java | 2 +- .../MUTCDCodeSerializer.java | 2 +- .../MinutesDuration.java | 2 +- .../{DSRC => travelerinformation}/MsgCRC.java | 2 +- .../NodeAttributeLL.java | 2 +- .../NodeAttributeLLDeserializer.java | 2 +- .../NodeAttributeLLList.java | 2 +- .../NodeAttributeLLSerializer.java | 2 +- .../NodeAttributeSetLL.java | 6 +- .../{DSRC => travelerinformation}/NodeLL.java | 2 +- .../NodeListLL.java | 2 +- .../NodeOffsetPointLL.java | 5 +- .../NodeSetLL.java | 2 +- .../Node_LL_24B.java | 3 +- .../Node_LL_28B.java | 3 +- .../Node_LL_32B.java | 3 +- .../Node_LL_36B.java | 3 +- .../Node_LL_44B.java | 3 +- .../Node_LL_48B.java | 3 +- .../OffsetSystem.java | 3 +- .../Radius_B12.java | 2 +- .../RegionList.java | 2 +- .../RegionOffsets.java | 3 +- .../RegionPointSet.java | 3 +- .../RoadSignID.java | 4 +- .../SegmentAttributeLL.java | 2 +- .../SegmentAttributeLLDeserializer.java | 2 +- .../SegmentAttributeLLList.java | 2 +- .../SegmentAttributeLLSerializer.java | 2 +- .../ShapePointSet.java | 5 +- .../SignPrority.java | 2 +- .../SpeedLimit.java | 2 +- .../SpeedLimitSequence.java | 4 +- .../TravelerDataFrame.java | 8 +- .../TravelerDataFrameList.java | 2 +- .../TravelerInfoType.java | 2 +- .../TravelerInfoTypeDeserializer.java | 2 +- .../TravelerInfoTypeSerializer.java | 2 +- .../TravelerInformation.java | 7 +- .../URL_Base.java | 2 +- .../URL_Short.java | 2 +- .../UniqueMSGID.java | 2 +- .../ValidRegion.java | 4 +- .../WorkZone.java | 2 +- .../WorkZoneSequence.java | 4 +- .../{DSRC => travelerinformation}/Zoom.java | 2 +- .../plugin/j2735/DSRC/HeadingSliceTest.java | 1 + .../ode/coder/OdeTimDataCreatorHelper.java | 2 +- 182 files changed, 243 insertions(+), 679 deletions(-) delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/DegreesLat.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/DegreesLong.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Elevation.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LaneDataAttribute_addGrpB.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LatitudeDMS.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LatitudeDMS2.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LongitudeDMS.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/LongitudeDMS2.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/MinutesAngle.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/NodeOffsetPointXY_addGrpB.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Node_LLdms_48b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Node_LLdms_80b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Position3D_addGrpB.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Position3D_addGrpBReg_Position3D.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Position3D_addGrpBReg_Position3DValueDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/Position3D_addGrpBReg_Position3DValueSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpB => addgrpb}/SecondsAngle.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/Altitude.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/AltitudeConfidence.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/AltitudeConfidenceDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/AltitudeConfidenceSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/AltitudeValue.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/Position3D_addGrpC.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/Position3D_addGrpCReg_Position3D.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/Position3D_addGrpCReg_Position3DValueDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{AddGrpC => addgrpc}/Position3D_addGrpCReg_Position3DValueSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Angle.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/ComputedLane.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/DYear.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/DeltaAngle.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/DescriptiveName.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/DrivenLineOffsetLg.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/DrivenLineOffsetSm.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Elevation.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Extent.java (98%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/ExtentDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/ExtentSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/FurtherInfoID.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/HeadingSlice.java (98%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/HeadingSliceDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/LaneDataAttribute.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/LaneDataAttributeList.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/LaneID.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/LaneWidth.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Latitude.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Longitude.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/MergeDivergeNodeAngle.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/MinuteOfTheYear.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/MsgCount.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeAttributeSetXY.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeAttributeXY.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeAttributeXYDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeAttributeXYList.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeAttributeXYSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeListXY.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeOffsetPointXY.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeSetXY.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/NodeXY.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_LLmD_64b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_20b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_22b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_24b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_26b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_28b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Node_XY_32b.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B12.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B14.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B16.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B18.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B22.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/OffsetLL_B24.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B10.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B11.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B12.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B13.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B14.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Offset_B16.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Position3D.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RegionId.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RegionalExtension.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RegulatorySpeedLimit.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RoadRegulatorID.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RoadSegmentID.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RoadSegmentReferenceID.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/RoadwayCrownAngle.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SSPindex.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Scale_B12.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SegmentAttributeXY.java (99%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SegmentAttributeXYDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SegmentAttributeXYList.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SegmentAttributeXYSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SpeedLimitList.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SpeedLimitType.java (98%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SpeedLimitTypeDeserializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/SpeedLimitTypeSerializer.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/Velocity.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{ITIS => itis}/ITIScodes.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{ITIS => itis}/ITIScodesAndText.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{ITIS => itis}/ITIScodesAndTextSequence.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{ITIS => itis}/ITIStext.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_ComputedLane.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_GeographicalPath.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_GeometricProjection.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_LaneDataAttribute.java (92%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_NodeAttributeSetLL.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_NodeAttributeSetXY.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_NodeOffsetPointLL.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_NodeOffsetPointXY.java (92%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_Position3D.java (90%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{REGION => region}/Reg_TravelerInformation.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Circle.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DirectionOfUse.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DirectionOfUseDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DirectionOfUseSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DistanceUnits.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DistanceUnitsDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/DistanceUnitsSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/ExitService.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/ExitServiceSequence.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/GenericSignage.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/GenericSignageSequence.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/GeographicalPath.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/GeometricProjection.java (88%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/ITIStextPhrase.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/MUTCDCode.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/MUTCDCodeDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/MUTCDCodeSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/MinutesDuration.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/MsgCRC.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeAttributeLL.java (97%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeAttributeLLDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeAttributeLLList.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeAttributeLLSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeAttributeSetLL.java (92%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeLL.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeListLL.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeOffsetPointLL.java (92%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/NodeSetLL.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_24B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_28B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_32B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_36B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_44B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Node_LL_48B.java (93%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/OffsetSystem.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Radius_B12.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/RegionList.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/RegionOffsets.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/RegionPointSet.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/RoadSignID.java (90%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SegmentAttributeLL.java (98%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SegmentAttributeLLDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SegmentAttributeLLList.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SegmentAttributeLLSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/ShapePointSet.java (89%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SignPrority.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SpeedLimit.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/SpeedLimitSequence.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerDataFrame.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerDataFrameList.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerInfoType.java (96%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerInfoTypeDeserializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerInfoTypeSerializer.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/TravelerInformation.java (91%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/URL_Base.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/URL_Short.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/UniqueMSGID.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/ValidRegion.java (92%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/WorkZone.java (95%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/WorkZoneSequence.java (94%) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => travelerinformation}/Zoom.java (96%) diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java index 37cea2c0a..a0466e197 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java @@ -16,7 +16,7 @@ package us.dot.its.jpo.ode.model; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.TravelerInformation; +import us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation; public class OdeTimPayload extends OdeMsgPayload { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak deleted file mode 100644 index cfe03e8ef..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java_bak +++ /dev/null @@ -1,355 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodesAndText; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; -import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -/** - * EDITED: Fixed "notUsed" properties. - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

- * - *
- * J2735_201603DA.ASN
- * 
- * - */ -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class TravelerDataFrame extends Asn1Sequence { - - @Asn1Property(tag = 0) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) - private SSPindex notUsed; - @Asn1Property(tag = 1) - private TravelerInfoType frameType; - @Asn1Property(tag = 2) - private MsgIdChoice msgId; - @Asn1Property(tag = 3, optional = true) - @JsonDeserialize(using = DYear.DYearDeserializer.class) - private DYear startYear; - @Asn1Property(tag = 4) - @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) - private MinuteOfTheYear startTime; - @Asn1Property(tag = 5) - @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) - private MinutesDuration duratonTime; - @Asn1Property(tag = 6) - @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) - private SignPrority priority; - @Asn1Property(tag = 7) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) - private SSPindex notUsed1; - @Asn1Property(tag = 8) - private SequenceOfRegions regions; - @Asn1Property(tag = 9) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) - private SSPindex notUsed2; - @Asn1Property(tag = 10) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) - private SSPindex notUsed3; - @Asn1Property(tag = 11) - private ContentChoice content; - @Asn1Property(tag = 12, optional = true) - private URL_Short url; - - public SSPindex getNotUsed() { - return notUsed; - } - - public void setNotUsed(SSPindex notUsed) { - this.notUsed = notUsed; - } - - public TravelerInfoType getFrameType() { - return frameType; - } - - public void setFrameType(TravelerInfoType frameType) { - this.frameType = frameType; - } - - @JsonInclude(Include.NON_NULL) - public static class MsgIdChoice extends Asn1Choice { - @Asn1Property(tag = 0) - private FurtherInfoID furtherInfoID; - @Asn1Property(tag = 1) - private RoadSignID roadSignID; - - MsgIdChoice() { - super(false); - } - - public FurtherInfoID getFurtherInfoID() { - return furtherInfoID; - } - - public void setFurtherInfoID(FurtherInfoID furtherInfoID) { - this.furtherInfoID = furtherInfoID; - } - - public RoadSignID getRoadSignID() { - return roadSignID; - } - - public void setRoadSignID(RoadSignID roadSignID) { - this.roadSignID = roadSignID; - } - - @Override - protected List> listTypes() { - return null; - } - } - - public MsgIdChoice getMsgId() { - return msgId; - } - - public void setMsgId(MsgIdChoice msgId) { - this.msgId = msgId; - } - - public DYear getStartYear() { - return startYear; - } - - public void setStartYear(DYear startYear) { - this.startYear = startYear; - } - - public MinuteOfTheYear getStartTime() { - return startTime; - } - - public void setStartTime(MinuteOfTheYear startTime) { - this.startTime = startTime; - } - - public MinutesDuration getDuratonTime() { - return duratonTime; - } - - public void setDuratonTime(MinutesDuration duratonTime) { - this.duratonTime = duratonTime; - } - - public SignPrority getPriority() { - return priority; - } - - public void setPriority(SignPrority priority) { - this.priority = priority; - } - - public SSPindex getNotUsed1() { - return notUsed1; - } - - public void setNotUsed1(SSPindex notUsed1) { - this.notUsed1 = notUsed1; - } - - @JsonInclude(Include.NON_NULL) - public static class SequenceOfRegions extends Asn1SequenceOf { - SequenceOfRegions() { - super(GeographicalPath.class, 1L, 16L); - } - } - - public SequenceOfRegions getRegions() { - return regions; - } - - public void setRegions(SequenceOfRegions regions) { - this.regions = regions; - } - - public SSPindex getNotUsed2() { - return notUsed2; - } - - public void setNotUsed2(SSPindex notUsed2) { - this.notUsed2 = notUsed2; - } - - public SSPindex getNotUsed3() { - return notUsed3; - } - - public void setNotUsed3(SSPindex notUsed3) { - this.notUsed3 = notUsed3; - } - - @JsonInclude(Include.NON_NULL) - public static class ContentChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = AdvisoryDeserializer.class) - @JsonSerialize(using = AdvisorySerializer.class) - private ITIScodesAndText advisory; - @Asn1Property(tag = 1) - @JsonDeserialize(using = WorkZoneDeserializer.class) - @JsonSerialize(using = WorkZoneSerializer.class) - private WorkZone workZone; - @Asn1Property(tag = 2) - @JsonDeserialize(using = GenericSignDeserializer.class) - @JsonSerialize(using = GenericSignSerializer.class) - private GenericSignage genericSign; - @Asn1Property(tag = 3) - @JsonDeserialize(using = SpeedLimitDeserializer.class) - @JsonSerialize(using = SpeedLimitSerializer.class) - private SpeedLimit speedLimit; - @Asn1Property(tag = 4) - @JsonDeserialize(using = ExitServiceDeserializer.class) - @JsonSerialize(using = ExitServiceSerializer.class) - private ExitService exitService; - - ContentChoice() { - super(false); - } - - public ITIScodesAndText getAdvisory() { - return advisory; - } - - public void setAdvisory(ITIScodesAndText advisory) { - this.advisory = advisory; - } - - public WorkZone getWorkZone() { - return workZone; - } - - public void setWorkZone(WorkZone workZone) { - this.workZone = workZone; - } - - public GenericSignage getGenericSign() { - return genericSign; - } - - public void setGenericSign(GenericSignage genericSign) { - this.genericSign = genericSign; - } - - public SpeedLimit getSpeedLimit() { - return speedLimit; - } - - public void setSpeedLimit(SpeedLimit speedLimit) { - this.speedLimit = speedLimit; - } - - public ExitService getExitService() { - return exitService; - } - - public void setExitService(ExitService exitService) { - this.exitService = exitService; - } - - @Override - protected List> listTypes() { - return null; - } - } - - public ContentChoice getContent() { - return content; - } - - public void setContent(ContentChoice content) { - this.content = content; - } - - public URL_Short getUrl() { - return url; - } - - public void setUrl(URL_Short url) { - this.url = url; - } - - TravelerDataFrame() { - super(true); - } - - public static class AdvisoryDeserializer extends NestedSequenceOfDeserializer { - public AdvisoryDeserializer() { - super(ITIScodesAndText.class, "SEQUENCE"); - } - } - - public static class AdvisorySerializer extends NestedSequenceOfSerializer { - public AdvisorySerializer() { - super(ITIScodesAndText.class, "SEQUENCE"); - } - } - - public static class WorkZoneDeserializer extends NestedSequenceOfDeserializer { - public WorkZoneDeserializer() { - super(WorkZone.class, "SEQUENCE"); - } - } - - public static class WorkZoneSerializer extends NestedSequenceOfSerializer { - public WorkZoneSerializer() { - super(WorkZone.class, "SEQUENCE"); - } - } - - public static class GenericSignDeserializer extends NestedSequenceOfDeserializer { - public GenericSignDeserializer() { - super(GenericSignage.class, "SEQUENCE"); - } - } - - public static class GenericSignSerializer extends NestedSequenceOfSerializer { - public GenericSignSerializer() { - super(GenericSignage.class, "SEQUENCE"); - } - } - - public static class SpeedLimitDeserializer extends NestedSequenceOfDeserializer { - public SpeedLimitDeserializer() { - super(SpeedLimit.class, "SEQUENCE"); - } - } - - public static class SpeedLimitSerializer extends NestedSequenceOfSerializer { - public SpeedLimitSerializer() { - super(SpeedLimit.class, "SEQUENCE"); - } - } - - public static class ExitServiceDeserializer extends NestedSequenceOfDeserializer { - public ExitServiceDeserializer() { - super(ExitService.class, "SEQUENCE"); - } - } - - public static class ExitServiceSerializer extends NestedSequenceOfSerializer { - public ExitServiceSerializer() { - super(ExitService.class, "SEQUENCE"); - } - } -} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak deleted file mode 100644 index 804a14f63..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java_bak +++ /dev/null @@ -1,111 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; - -//import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; - -/** - * EDITED: Changed base class to Asn1Object. - *

- * This source code was generated by a tool. Manual edits are futile. - *

- *

- * asn1jvm v1.0-SNAPSHOT - *

- *

- * ASN.1 source files: - *

- * - *
- * J2735_201603DA.ASN
- * 
- * - */ -@JsonInclude(Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class TravelerInformation extends Asn1Object { - - @Asn1Property(tag = 0) - @JsonDeserialize(using = MsgCount.MsgCountDeserializer.class) - private MsgCount msgCnt; - @Asn1Property(tag = 1, optional = true) - @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) - private MinuteOfTheYear timeStamp; - @Asn1Property(tag = 2, optional = true) - private UniqueMSGID packetID; - @Asn1Property(tag = 3, optional = true) - private URL_Base urlB; - @Asn1Property(tag = 4) - @JacksonXmlElementWrapper(localName = "dataFrames") - @JacksonXmlProperty(localName = "TravelerDataFrame") - private TravelerDataFrameList dataFrames; - @Asn1Property(tag = 5, optional = true) - private SequenceOfRegional regional; - - public MsgCount getMsgCnt() { - return msgCnt; - } - - public void setMsgCnt(MsgCount msgCnt) { - this.msgCnt = msgCnt; - } - - public MinuteOfTheYear getTimeStamp() { - return timeStamp; - } - - public void setTimeStamp(MinuteOfTheYear timeStamp) { - this.timeStamp = timeStamp; - } - - public UniqueMSGID getPacketID() { - return packetID; - } - - public void setPacketID(UniqueMSGID packetID) { - this.packetID = packetID; - } - - public URL_Base getUrlB() { - return urlB; - } - - public void setUrlB(URL_Base urlB) { - this.urlB = urlB; - } - - public TravelerDataFrameList getDataFrames() { - return dataFrames; - } - - public void setDataFrames(TravelerDataFrameList dataFrames) { - this.dataFrames = dataFrames; - } - - @JsonInclude(Include.NON_NULL) - public static class SequenceOfRegional extends Asn1SequenceOf { - SequenceOfRegional() { - super(us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation.class, 1L, 4L); - } - } - - public SequenceOfRegional getRegional() { - return regional; - } - - public void setRegional(SequenceOfRegional regional) { - this.regional = regional; - } - - // TravelerInformation() { - // super(true); - // } -} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java index ea73f2537..ff18a437c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLat.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java index 32e97c7a2..5dccdd43c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/DegreesLong.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java index 21a1d67f0..10fea8d79 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java index 6a8596d1e..ab7e1bb75 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java index 8cdd2bf74..95943a384 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java @@ -1,7 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java index f00fe29aa..4ffa829a2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java index 34604a6c5..3b81922f9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java index 4afd65dcd..39c9544b8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java index 8b256dda5..96b95f99f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LatitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java index 8a2f506b0..684a69bd7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java index 7654c3a49..3f6ea906b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/LongitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java index c84d8d850..0d0a221b1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/MinutesAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java index 029269f47..604133f8a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java index bcc1722bd..1555a9d9e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java @@ -1,7 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointXY; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java index 2344e977e..5dc245e26 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java index 0f5fd8d5e..00e8dbb98 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java index 74d3f60b2..1713a3328 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_48b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java index b8fead586..36fac5ed0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Node_LLdms_80b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java index 61bbcddc3..5b8146824 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java index dea08570a..04ecf4e39 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java @@ -1,7 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java index 323cee785..e2107d551 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java index de281a657..2103b40b8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/Position3D_addGrpBReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java index 694530556..8178aa106 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpB/SecondsAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpB; +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java index bd3ec24c7..fe678d880 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Altitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java index 79717dc3d..2039629f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java index 903cda72c..c12e33d2d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java index a71c84133..f24b494d7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeConfidenceSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java index 4c7f21602..d7c7ba0e3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/AltitudeValue.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java index 9c271ad64..85c0dfa1f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java index a0cfb8ea5..3a09e4f61 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java @@ -1,7 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java index 86fd9fcc9..f4871f3dd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java index 6de20e887..dba7643ba 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/AddGrpC/Position3D_addGrpCReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.AddGrpC; +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java index d0dc9dd0d..a4b45ab87 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Angle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java index 843a44660..1e8169cd9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; @@ -11,7 +11,7 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_ComputedLane; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_ComputedLane; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java index 302c1f6c4..17c229bb9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java index 5d632870f..3dcecb25d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DeltaAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java index 209d62c92..fcb3562d8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DescriptiveName.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.IA5String; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java index bde781fb0..2a1693bf1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetLg.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java index 8a0c983d1..321f5e403 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DrivenLineOffsetSm.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java index fe6af2266..c1a2dd49f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java similarity index 98% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java index 3b6af79ff..4c37d2047 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java index 27adb0aca..e2552a24d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java index 2ff569353..58a9f53e6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExtentSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java index e15b0e398..f6e89eeff 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/FurtherInfoID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java similarity index 98% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java index 8ded5b3c7..2d79f0c9c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSlice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java index 9c307388d..d2ff8085c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.BitStringDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java index 9da23b8cf..eb41a08cf 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java @@ -1,10 +1,10 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import java.util.Optional; import java.util.List; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java index d3b770fc7..22af32c0a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java index 721c384e2..d936442fd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java index eed9f59e3..9501bbc96 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/LaneWidth.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java index df8cd9661..22137e9eb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Latitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java index 15f170200..4184924b0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Longitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java index e5886ccc0..19c61d8ae 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MergeDivergeNodeAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java index 47ace2e45..e2bd1edf4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinuteOfTheYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java index c34e0b6ef..98f1c6fb8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCount.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java index 3a0bcece0..c8ce8ca5b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; @@ -7,7 +7,7 @@ import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetXY; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeAttributeSetXY; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java index b71a0694f..fa99c7604 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java index 92875722d..0259fc5dc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java index 0cf0e274c..18cac154a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java index f44a009a9..b463c0300 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java index ee341ab76..34bf65551 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java index e3a1db4ef..f0bd1b166 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java @@ -1,11 +1,11 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointXY; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; import java.util.Optional; import java.util.List; import us.dot.its.jpo.ode.plugin.types.Asn1Type; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java index c61b29358..b7dfa2aa7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java index 8d515eebb..b6cc8a04b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java index ba38d3954..59055849e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LLmD_64b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java index 67f04a51f..d0066ba70 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_20b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java index 8a10cfc34..919cf175b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_22b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java index 9d9a5f16d..a43dc1063 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_24b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java index a38aa0ff0..a1a51aa56 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_26b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java index 0847fbdeb..3e1a7286b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_28b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java index 15f837c63..dac1b425c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_XY_32b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java index b5e1d9638..252e7b646 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java index bed70b10b..a80b1baa1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java index f387a6f5b..ed1d6b972 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java index 89976805d..00390c1a2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B18.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java index 0c68b8470..ab1a3fb3f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B22.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java index e7e3320f6..5c9f8ac1f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetLL_B24.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java index 7059da2c5..b690c2a6d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B10.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java index b475f1ae7..e61837b32 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B11.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java index 363dc133f..0d8616b48 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java index f825ac517..b1deca14a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B13.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java index 0c006d132..98f41e859 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java index d0d02996d..118af18cd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Offset_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java index d69ca2954..981acd100 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; @@ -8,7 +8,7 @@ import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java index 6213f3ea2..b4e67d810 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java index 707a1e3f7..3fd317611 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionalExtension.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java index 44214b7b6..4c614a605 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java index 69a71723a..c6306bd10 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadRegulatorID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java index 1600c20bf..f17376267 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java index 9d6a4c0d6..a8c1bfdaa 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSegmentReferenceID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java index a1568b765..8d9d168f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadwayCrownAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java index 02738fb21..10a9e6fdc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SSPindex.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java index f9e6c41c5..2d22269be 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Scale_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java similarity index 99% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java index 18931898f..47d517b09 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java index fc694eea5..05bf3e958 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java index d128cf679..c49e2831c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java index 6fe24c6aa..197276af0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java index 866f454d4..d9afbcc34 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java similarity index 98% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java index add530a57..41c14c7fb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java index be7db2377..e05b38fdd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java index 0163b370d..42ca329a9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java index 903873564..4a056a83e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Velocity.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java index 2e43436b9..a1533f7bf 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.ITIS; +package us.dot.its.jpo.ode.plugin.j2735.itis; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java index ee5bf9b34..10263c63a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndText.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.ITIS; +package us.dot.its.jpo.ode.plugin.j2735.itis; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java index 8170f1ff3..e7cbc6926 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIScodesAndTextSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.ITIS; +package us.dot.its.jpo.ode.plugin.j2735.itis; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java index 213baae24..6af08f7e5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/ITIS/ITIStext.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.ITIS; +package us.dot.its.jpo.ode.plugin.j2735.itis; import us.dot.its.jpo.ode.plugin.types.IA5String; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java index a9fa04d1a..3410edc35 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java index 6ef13814f..9c629cc83 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java index 00a482bb2..711b68a85 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java similarity index 92% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java index 1b64c7495..4c2319fcc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java @@ -1,15 +1,15 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; -import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.LaneDataAttribute_addGrpBReg_LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.j2735.addgrpb.LaneDataAttribute_addGrpBReg_LaneDataAttribute; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java index 07e386bc8..609034278 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java index 82bc64922..e2c39d8f7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java index 9cccb2a02..7ecbbd259 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java similarity index 92% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java index 86074ae06..56bc82e1f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java @@ -1,15 +1,15 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; -import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY; +import us.dot.its.jpo.ode.plugin.j2735.addgrpb.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java similarity index 90% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java index 0c785e5be..29ddd373b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java @@ -1,16 +1,16 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; import com.fasterxml.jackson.annotation.JsonSubTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; -import us.dot.its.jpo.ode.plugin.j2735.AddGrpB.Position3D_addGrpBReg_Position3D; -import us.dot.its.jpo.ode.plugin.j2735.AddGrpC.Position3D_addGrpCReg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.addgrpb.Position3D_addGrpBReg_Position3D; +import us.dot.its.jpo.ode.plugin.j2735.addgrpc.Position3D_addGrpCReg_Position3D; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java index d2ba1b9da..6a817cb5b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/REGION/Reg_TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java @@ -1,8 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.REGION; +package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.RegionalExtension; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; /** * diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java index 32d6f2325..13fe811df 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java index 46e7b4757..da671f402 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java index e9ff794f6..0c5b4c673 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java index 1337c92ab..17b71f89c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DirectionOfUseSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java index 4051b56c6..7de461351 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java index 2fe639254..62c5e9233 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java index 1214e84de..d0d7c9848 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/DistanceUnitsSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java index 9eb660042..28b0db664 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitService.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java index e5bc0b622..e45be02f8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ExitServiceSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java @@ -1,10 +1,10 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; import java.util.Optional; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java index c9a1f2e48..48d2230ab 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java index b7c3e3aca..8c9c20877 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GenericSignageSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java @@ -1,10 +1,10 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; import java.util.Optional; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java index 9d3d12b49..4251898bd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.*; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -12,7 +13,7 @@ import java.util.List; import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeographicalPath; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_GeographicalPath; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java similarity index 88% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java index 4d61a2b9b..d1d76f883 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java @@ -1,5 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.Extent; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -7,7 +10,7 @@ import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_GeometricProjection; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_GeometricProjection; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java index b84fbb099..8dc8a0631 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ITIStextPhrase.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.IA5String; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java index 7dba15957..66947881e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCode.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java index b67f017c5..a699b83e2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java index 4ee4a94b4..cd570d7cc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MUTCDCodeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java index 63664052a..5a8b5a919 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MinutesDuration.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java index 6606f5ec8..44dcfdb01 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/MsgCRC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java similarity index 97% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java index 573e8f895..cb089e5f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java index 9854db23f..327ba21d1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java index 29f77a0bd..8772cad1b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java index e616bbd24..1d74fa8dc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java similarity index 92% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java index 2617746dd..c52a2f41e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java @@ -1,5 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneDataAttributeList; +import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -7,7 +9,7 @@ import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeAttributeSetLL; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeAttributeSetLL; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java index 32ab8e66c..17596168e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java index 9cc390cd7..f16e9cb93 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java similarity index 92% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java index bae1cd87a..c0caf658f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java @@ -1,11 +1,12 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.Node_LLmD_64b; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_NodeOffsetPointLL; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointLL; import java.util.Optional; import java.util.List; import us.dot.its.jpo.ode.plugin.types.Asn1Type; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java index 83eaa5b1b..aafce72c7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/NodeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java index efafc4339..574f7165f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_24B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B12; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java index fae4ecdbb..065861345 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_28B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B14; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java index df36b4c3a..b1f6274ba 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_32B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java index 6583e78a5..625fd2dc7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_36B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B18; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java index a14c641db..40499b07e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_44B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B22; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java similarity index 93% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java index e5946e86d..0e906159f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Node_LL_48B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B24; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java index ad999cc1e..aac5dc2af 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java index c328df226..c4de7e997 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Radius_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java index 0bf8005f0..963ea6bf2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java index 6adab3e16..ad689e04b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java index 30cf329b1..613faf01e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java @@ -1,5 +1,6 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java similarity index 90% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java index de9148479..fcdf96ac2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/RoadSignID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java @@ -1,5 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java similarity index 98% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java index 2a0ffc1ec..e8e0827e5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java index dcad42c12..1a765b7d7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java index dcc7cf380..4b0b2b36d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java index f17cb1d73..ec5a9f31b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SegmentAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java similarity index 89% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java index dae1fd519..e2bb76be4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java @@ -1,5 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; +import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java index b74fbd134..a3335e2fe 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SignPrority.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java index 5a4c2fc93..840dc1a0f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java index 623c1c48d..382e88f2e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/SpeedLimitSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java @@ -1,10 +1,10 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; import java.util.Optional; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java index fcd68f442..6fe034246 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java @@ -1,5 +1,9 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.DYear; +import us.dot.its.jpo.ode.plugin.j2735.common.FurtherInfoID; +import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; +import us.dot.its.jpo.ode.plugin.j2735.common.SSPindex; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -12,7 +16,7 @@ import java.util.Optional; import us.dot.its.jpo.ode.plugin.types.Asn1Type; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodesAndText; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodesAndText; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java index d1d89e199..0842e5c0b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerDataFrameList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java index 323267c8f..60b430f05 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import lombok.Getter; import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java index 15cf06ae1..cbd2b76b9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java index 23c31bc60..4b59b649a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInfoTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java similarity index 91% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java index 6a7cc99eb..acc409ab7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java @@ -1,14 +1,15 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.REGION.Reg_TravelerInformation; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_TravelerInformation; +import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; +import us.dot.its.jpo.ode.plugin.j2735.common.MsgCount; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java index 62909df7a..0d0bb8e67 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Base.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.IA5String; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java index 54e2c0329..11e75d3a6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/URL_Short.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.IA5String; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java index 433cba1e7..5bce94e6b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/UniqueMSGID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java similarity index 92% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java index 2772b975d..e331f99e2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java @@ -1,5 +1,7 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import us.dot.its.jpo.ode.plugin.j2735.common.Extent; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java similarity index 95% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java index 01059af20..c561e4e04 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZone.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.annotation.JsonInclude; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java similarity index 94% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java index 697950888..da8de75fe 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/WorkZoneSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java @@ -1,10 +1,10 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.ITIS.ITIScodes; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; import java.util.List; import java.util.Optional; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java similarity index 96% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java index 988311b91..178ebad5b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/Zoom.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.annotation.JsonCreator; diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java index 47e4c1405..f71e623ee 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; import static org.junit.jupiter.api.Assertions.*; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index d3b58b204..9c60aed6b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -14,7 +14,7 @@ import us.dot.its.jpo.ode.model.OdeTimPayload; import us.dot.its.jpo.ode.model.ReceivedMessageDetails; import us.dot.its.jpo.ode.model.RxSource; -import us.dot.its.jpo.ode.plugin.j2735.DSRC.TravelerInformation; +import us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation; import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; From ff5a742c04b35e0853288203855b99b3417a0b6b Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Wed, 4 Dec 2024 18:01:47 -0700 Subject: [PATCH 125/264] Fix test namespace --- .../ode/plugin/j2735/{DSRC => common}/HeadingSliceTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/{DSRC => common}/HeadingSliceTest.java (93%) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java similarity index 93% rename from jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java rename to jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java index f71e623ee..50d1cf62b 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/DSRC/HeadingSliceTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java @@ -1,9 +1,8 @@ -package us.dot.its.jpo.ode.plugin.j2735.DSRC; +package us.dot.its.jpo.ode.plugin.j2735.common; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; import static org.junit.jupiter.api.Assertions.*; From c726baaf36ec8e744d3e57ce029988f5ffffca17 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Thu, 5 Dec 2024 04:02:24 -0700 Subject: [PATCH 126/264] Remove unused older POJOs and update the TIM test with a better XML test case for testing deserialization of XER and serialization into JSON --- .../ode/plugin/j2735/J2735Description.java | 35 - .../ode/plugin/j2735/J2735DirectionOfUse.java | 23 - .../plugin/j2735/J2735GeographicalPath.java | 71 -- .../j2735/J2735GeometricProjection.java | 45 - .../ode/plugin/j2735/J2735HeadingSlice.java | 20 - .../its/jpo/ode/plugin/j2735/J2735NodeLL.java | 27 - .../jpo/ode/plugin/j2735/J2735NodeListLL.java | 17 - .../plugin/j2735/J2735NodeOffsetPointLL.java | 72 -- .../jpo/ode/plugin/j2735/J2735Node_LL.java | 53 - .../its/jpo/ode/plugin/j2735/J2735Offset.java | 26 - .../ode/plugin/j2735/J2735OffsetSystem.java | 26 - .../its/jpo/ode/plugin/j2735/J2735Tim.java | 53 - .../plugin/j2735/J2735TravelerDataFrame.java | 126 --- .../plugin/j2735/J2735TravelerInfoType.java | 8 - .../builders/GeographicalPathBuilder.java | 89 -- .../plugin/j2735/builders/NodeLLBuilder.java | 185 ---- .../j2735/builders/NodeListLLBuilder.java | 41 - .../j2735/builders/OffsetSystemBuilder.java | 39 - .../ode/plugin/j2735/builders/TIMBuilder.java | 67 -- .../builders/TravelerDataFrameBuilder.java | 122 --- .../plugin/j2735/J2735DirectionOfUseTest.java | 42 - .../plugin/j2735/builders/TimBuilderTest.java | 30 - .../ode/coder/OdeTimDataCreatorHelper.java | 3 - .../coder/OdeTimDataCreatorHelperTest.java | 42 + .../OdeTimDataCreatorHelper_TIM_JSON.json | 1 + .../OdeTimDataCreatorHelper_TIM_XER.xml | 989 ++++++++++++++++++ 26 files changed, 1032 insertions(+), 1220 deletions(-) delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java delete mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java delete mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java delete mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json create mode 100644 jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java deleted file mode 100644 index c36022d89..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Description.java +++ /dev/null @@ -1,35 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735Description extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735OffsetSystem path; - private J2735GeometricProjection geometry; - private String oldRegion; //TODO - - public J2735OffsetSystem getPath() { - return path; - } - - public void setPath(J2735OffsetSystem path) { - this.path = path; - } - - public J2735GeometricProjection getGeometry() { - return geometry; - } - - public void setGeometry(J2735GeometricProjection geometry) { - this.geometry = geometry; - } - - public String getOldRegion() { - return oldRegion; - } - - public void setOldRegion(String oldRegion) { - this.oldRegion = oldRegion; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java deleted file mode 100644 index 3a44d0349..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUse.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.plugin.j2735; - -public enum J2735DirectionOfUse { - unavailable, - forward, - reverse, - both -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java deleted file mode 100644 index 6f7ddcf64..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeographicalPath.java +++ /dev/null @@ -1,71 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735GeographicalPath extends Asn1Object { - private static final long serialVersionUID = 1L; - - private String name; - private J2735RoadSegmentReferenceID id; - private OdePosition3D anchor; - private int laneWidth; - private J2735DirectionOfUse directionality; - private boolean closedPath; - private J2735Description description; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public J2735RoadSegmentReferenceID getId() { - return id; - } - - public void setId(J2735RoadSegmentReferenceID id) { - this.id = id; - } - - public OdePosition3D getAnchor() { - return anchor; - } - - public void setAnchor(OdePosition3D anchor) { - this.anchor = anchor; - } - - public int getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(int laneWidth) { - this.laneWidth = laneWidth; - } - - public J2735DirectionOfUse getDirectionality() { - return directionality; - } - - public void setDirectionality(J2735DirectionOfUse directionality) { - this.directionality = directionality; - } - - public boolean getClosedPath() { - return closedPath; - } - - public void setClosedPath(boolean closedPath) { - this.closedPath = closedPath; - } - - public J2735Description getDescription() { - return description; - } - - public void setDescription(J2735Description description) { - this.description = description; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java deleted file mode 100644 index 81a8bfe38..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735GeometricProjection.java +++ /dev/null @@ -1,45 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.Circle; - -public class J2735GeometricProjection extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735HeadingSlice direction; - private J2735Extent extent; - private String laneWidth; - private Circle circle; - - public J2735HeadingSlice getDirection() { - return direction; - } - - public void setDirection(J2735HeadingSlice direction) { - this.direction = direction; - } - - public J2735Extent getExtent() { - return extent; - } - - public void setExtent(J2735Extent extent) { - this.extent = extent; - } - - public String getLaneWidth() { - return laneWidth; - } - - public void setLaneWidth(String laneWidth) { - this.laneWidth = laneWidth; - } - - public Circle getCircle() { - return circle; - } - - public void setCircle(Circle circle) { - this.circle = circle; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java deleted file mode 100644 index ad11b8a7b..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735HeadingSlice.java +++ /dev/null @@ -1,20 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -public enum J2735HeadingSlice { - from000_0to022_5degrees, - from022_5to045_0degrees, - from045_0to067_5degrees, - from067_5to090_0degrees, - from090_0to112_5degrees, - from112_5to135_0degrees, - from135_0to157_5degrees, - from157_5to180_0degrees, - from180_0to202_5degrees, - from202_5to225_0degrees, - from225_0to247_5degrees, - from247_5to270_0degrees, - from270_0to292_5degrees, - from292_5to315_0degrees, - from315_0to337_5degrees, - from337_5to360_0degrees -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java deleted file mode 100644 index 4ac84417a..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeLL.java +++ /dev/null @@ -1,27 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeLL extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735NodeOffsetPointLL delta; - private J2735NodeAttributeSet attributes; - - public J2735NodeOffsetPointLL getDelta() { - return delta; - } - - public void setDelta(J2735NodeOffsetPointLL delta) { - this.delta = delta; - } - - public J2735NodeAttributeSet getAttributes() { - return attributes; - } - - public void setAttributes(J2735NodeAttributeSet attributes) { - this.attributes = attributes; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java deleted file mode 100644 index 009650712..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeListLL.java +++ /dev/null @@ -1,17 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeListLL extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735NodeLL[] nodes; - - public J2735NodeLL[] getNodes() { - return nodes; - } - - public void setNodes(J2735NodeLL[] nodes) { - this.nodes = nodes; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java deleted file mode 100644 index 2465bbadb..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735NodeOffsetPointLL.java +++ /dev/null @@ -1,72 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735NodeOffsetPointLL extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735Node_LL nodeLL1; - private J2735Node_LL nodeLL2; - private J2735Node_LL nodeLL3; - private J2735Node_LL nodeLL4; - private J2735Node_LL nodeLL5; - private J2735Node_LL nodeLL6; - private J2735NodeLLmD64b nodeLatLon; - - public J2735Node_LL getNodeLL1() { - return nodeLL1; - } - - public void setNodeLL1(J2735Node_LL nodeLL1) { - this.nodeLL1 = nodeLL1; - } - - public J2735Node_LL getNodeLL2() { - return nodeLL2; - } - - public void setNodeLL2(J2735Node_LL nodeLL2) { - this.nodeLL2 = nodeLL2; - } - - public J2735Node_LL getNodeLL3() { - return nodeLL3; - } - - public void setNodeLL3(J2735Node_LL nodeLL3) { - this.nodeLL3 = nodeLL3; - } - - public J2735Node_LL getNodeLL4() { - return nodeLL4; - } - - public void setNodeLL4(J2735Node_LL nodeLL4) { - this.nodeLL4 = nodeLL4; - } - - public J2735Node_LL getNodeLL5() { - return nodeLL5; - } - - public void setNodeLL5(J2735Node_LL nodeLL5) { - this.nodeLL5 = nodeLL5; - } - - public J2735Node_LL getNodeLL6() { - return nodeLL6; - } - - public void setNodeLL6(J2735Node_LL nodeLL6) { - this.nodeLL6 = nodeLL6; - } - - public J2735NodeLLmD64b getNodeLatLon() { - return nodeLatLon; - } - - public void setNodeLatLon(J2735NodeLLmD64b nodeLatLon) { - this.nodeLatLon = nodeLatLon; - } - -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java deleted file mode 100644 index fa3e18c36..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Node_LL.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.plugin.j2735; - -import java.math.BigDecimal; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735Node_LL extends Asn1Object { - private static final long serialVersionUID = 1L; - - private BigDecimal lon; - private BigDecimal lat; - - public J2735Node_LL() { - super(); - } - - public J2735Node_LL(BigDecimal lon, BigDecimal lat) { - super(); - this.lon = lon; - this.lat = lat; - } - - public BigDecimal getLon() { - return lon; - } - - public void setLon(BigDecimal lon) { - this.lon = lon; - } - - public BigDecimal getLat() { - return lat; - } - - public void setLat(BigDecimal lat) { - this.lat = lat; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java deleted file mode 100644 index 788cdc71b..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Offset.java +++ /dev/null @@ -1,26 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735Offset extends Asn1Object { - private static final long serialVersionUID = 1L; - - private J2735NodeListXY xy; - private J2735NodeListLL ll; - - public J2735NodeListXY getXY() { - return xy; - } - - public void setXY(J2735NodeListXY xy) { - this.xy = xy; - } - - public J2735NodeListLL getLL() { - return ll; - } - - public void setLL(J2735NodeListLL ll) { - this.ll = ll; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java deleted file mode 100644 index 186af2e1f..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735OffsetSystem.java +++ /dev/null @@ -1,26 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735OffsetSystem extends Asn1Object { - private static final long serialVersionUID = 1L; - - private int scale; - private J2735Offset offset; - - public int getScale() { - return scale; - } - - public void setScale(int scale) { - this.scale = scale; - } - - public J2735Offset getOffset() { - return offset; - } - - public void setOffset(J2735Offset offset) { - this.offset = offset; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java deleted file mode 100644 index 3be7eb30d..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735Tim.java +++ /dev/null @@ -1,53 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; - -public class J2735Tim extends Asn1Object { - private static final long serialVersionUID = 1L; - - private String msgCnt; - private String timeStamp; - private String packetID; - private String urlB; - private J2735TravelerDataFrame[] dataFrames; - - public String getMsgCnt() { - return msgCnt; - } - - public void setMsgCnt(String msgCnt) { - this.msgCnt = msgCnt; - } - - public String getTimeStamp() { - return timeStamp; - } - - public void setTimeStamp(String timeStamp) { - this.timeStamp = timeStamp; - } - - public String getPacketID() { - return packetID; - } - - public void setPacketID(String packetID) { - this.packetID = packetID; - } - - public String getUrlB() { - return urlB; - } - - public void setUrlB(String urlB) { - this.urlB = urlB; - } - - public J2735TravelerDataFrame[] getDataFrames() { - return dataFrames; - } - - public void setDataFrames(J2735TravelerDataFrame[] dataFrames) { - this.dataFrames = dataFrames; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java deleted file mode 100644 index 1093f1cc9..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerDataFrame.java +++ /dev/null @@ -1,126 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; -import us.dot.its.jpo.ode.plugin.j2735.timstorage.Content; - -public class J2735TravelerDataFrame extends Asn1Object { - private static final long serialVersionUID = 1L; - - private String notUsed; - private J2735TravelerInfoType frameType; - private J2735MsgId msgId; - private String startYear; - private String startTime; - private String durationTime; - private String priority; - private String notUsed1; - private J2735GeographicalPath[] regions; - private String notUsed2; - private String notUsed3; - private Content content; - private String url; - - public String getNotUsed() { - return notUsed; - } - - public void setNotUsed(String notUsed) { - this.notUsed = notUsed; - } - - public J2735TravelerInfoType getFrameType() { - return frameType; - } - - public void setFrameType(J2735TravelerInfoType frameType) { - this.frameType = frameType; - } - - public J2735MsgId getMsgId() { - return msgId; - } - - public void setMsgId(J2735MsgId msgId) { - this.msgId = msgId; - } - - public String getStartYear() { - return startYear; - } - - public void setStartYear(String startYear) { - this.startYear = startYear; - } - - public String getStartTime() { - return startTime; - } - - public void setStartTime(String startTime) { - this.startTime = startTime; - } - - public String getDurationTime() { - return durationTime; - } - - public void setDurationTime(String durationTime) { - this.durationTime = durationTime; - } - - public String getPriority() { - return priority; - } - - public void setPriority(String priority) { - this.priority = priority; - } - - public String getNotUsed1() { - return notUsed1; - } - - public void setNotUsed1(String notUsed1) { - this.notUsed1 = notUsed1; - } - - public J2735GeographicalPath[] getRegions() { - return regions; - } - - public void setRegions(J2735GeographicalPath[] regions) { - this.regions = regions; - } - - public String getNotUsed2() { - return notUsed2; - } - - public void setNotUsed2(String notUsed2) { - this.notUsed2 = notUsed2; - } - - public String getNotUsed3() { - return notUsed3; - } - - public void setNotUsed3(String notUsed3) { - this.notUsed3 = notUsed3; - } - - public Content getContent() { - return content; - } - - public void setContent(Content content) { - this.content = content; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java deleted file mode 100644 index 016f9b1d1..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/J2735TravelerInfoType.java +++ /dev/null @@ -1,8 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735; - -public enum J2735TravelerInfoType { - unknown, - advisory, - roadSignage, - commercialSignage, -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java deleted file mode 100644 index b5e6045ba..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/GeographicalPathBuilder.java +++ /dev/null @@ -1,89 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.DsrcPosition3D; -import us.dot.its.jpo.ode.plugin.j2735.J2735Description; -import us.dot.its.jpo.ode.plugin.j2735.J2735DirectionOfUse; -import us.dot.its.jpo.ode.plugin.j2735.J2735GeographicalPath; -import us.dot.its.jpo.ode.plugin.j2735.J2735RoadSegmentReferenceID; - -public class GeographicalPathBuilder { - private GeographicalPathBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735GeographicalPath genericGeographicalPath(JsonNode geographicalPath) { - J2735GeographicalPath genericGeographicalPath = new J2735GeographicalPath(); - - JsonNode name = geographicalPath.get("name"); - if (name != null) { - genericGeographicalPath.setName(name.asText()); - } - - JsonNode id = geographicalPath.get("id"); - if (id != null) { - J2735RoadSegmentReferenceID idObj = new J2735RoadSegmentReferenceID(); - - JsonNode idRegion = id.get("region"); - if (idRegion != null) { - idObj.setRegion(idRegion.asInt()); - } - - JsonNode idId = id.get("id"); - if (idId != null) { - idObj.setId(idId.asInt()); - } - - genericGeographicalPath.setId(idObj); - } - - JsonNode anchor = geographicalPath.get("anchor"); - if (anchor != null) { - DsrcPosition3D dsrcPosition3d = Position3DBuilder.dsrcPosition3D(anchor); - genericGeographicalPath.setAnchor(Position3DBuilder.odePosition3D(dsrcPosition3d)); - } - - JsonNode laneWidth = geographicalPath.get("laneWidth"); - if (laneWidth != null) { - genericGeographicalPath.setLaneWidth(laneWidth.asInt()); - } - - JsonNode directionality = geographicalPath.get("directionality"); - if (directionality != null) { - String directionalityValue = directionality.fields().next().getKey(); - genericGeographicalPath.setDirectionality(J2735DirectionOfUse.valueOf(directionalityValue)); - } - - JsonNode closedPath = geographicalPath.get("closedPath"); - if (closedPath != null) { - boolean closedPathValue = "true".equals(closedPath.fields().next().getKey()); - genericGeographicalPath.setClosedPath(closedPathValue); - } - - JsonNode description = geographicalPath.get("description"); - if (description != null) { - J2735Description descriptionObj = new J2735Description(); - - JsonNode path = description.get("path"); - if (path != null) { - descriptionObj.setPath(OffsetSystemBuilder.genericOffsetSystem(path)); - } - - JsonNode geometry = description.get("geometry"); - if (geometry != null) { - // RoadSignIdBuilder.genericRoadSignId(roadSignID) - descriptionObj.setGeometry(null); - } - - JsonNode oldRegion = description.get("oldRegion"); - if (oldRegion != null) { - descriptionObj.setOldRegion(null); - } - - genericGeographicalPath.setDescription(descriptionObj); - } - - return genericGeographicalPath; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java deleted file mode 100644 index 3d96b68c2..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeLLBuilder.java +++ /dev/null @@ -1,185 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735LaneDataAttribute; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttribute; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeAttributeSet; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLL; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLLmD64b; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeOffsetPointLL; -import us.dot.its.jpo.ode.plugin.j2735.J2735Node_LL; -import us.dot.its.jpo.ode.plugin.j2735.J2735SegmentAttribute; - -public class NodeLLBuilder { - private NodeLLBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735NodeLL genericNodeLL(JsonNode NodeJson) { - J2735NodeLL nodeLL = new J2735NodeLL(); - if (NodeJson.get("delta") != null) { - J2735NodeOffsetPointLL pointoffsetLL = new J2735NodeOffsetPointLL(); - JsonNode NodeOffsetNode = NodeJson.get("delta"); - if(NodeOffsetNode.get("node-LL1") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL1").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL1").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL1(point); - } - if(NodeOffsetNode.get("node-LL2") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL2").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL2").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL2(point); - } - if(NodeOffsetNode.get("node-LL3") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL3").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL3").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL3(point); - } - if(NodeOffsetNode.get("node-LL4") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL4").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL4").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL4(point); - } - if(NodeOffsetNode.get("node-LL5") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL5").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL5").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL5(point); - } - if(NodeOffsetNode.get("node-LL6") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LL6").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LL6").get("lat").asInt()); - J2735Node_LL point = new J2735Node_LL(lon,lat); - pointoffsetLL.setNodeLL6(point); - } - if(NodeOffsetNode.get("node-LatLon") != null) - { - BigDecimal lon =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lon").asInt()); - BigDecimal lat =BigDecimal.valueOf( NodeOffsetNode.get("node-LatLon").get("lat").asInt()); - J2735NodeLLmD64b point = new J2735NodeLLmD64b(lon,lat); - pointoffsetLL.setNodeLatLon(point); - } - nodeLL.setDelta(pointoffsetLL); - } - - if (NodeJson.get("attributes") != null) { - J2735NodeAttributeSet attributeSet = new J2735NodeAttributeSet(); - JsonNode attributes = NodeJson.get("attributes"); - - JsonNode localNode = attributes.get("localNode"); - if (localNode != null) { - JsonNode nodeAttributeLL = localNode.get("NodeAttributeLL"); - if (nodeAttributeLL != null) { - List naList = new ArrayList<>(); - - if (nodeAttributeLL.isArray()) { - Iterator elements = nodeAttributeLL.elements(); - - while (elements.hasNext()) { - String nodeAttributeValue = elements.next().fields().next().getKey(); - naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); - } - } else { - String nodeAttributeValue = nodeAttributeLL.fields().next().getKey(); - naList.add(J2735NodeAttribute.valueOf(nodeAttributeValue)); - } - - attributeSet.setLocalNode(naList.toArray(new J2735NodeAttribute[0])); - } - } - - JsonNode disabled = attributes.get("disabled"); - if (disabled != null) { - JsonNode segmentAttributeLL = disabled.get("SegmentAttributeLL"); - if (segmentAttributeLL != null) { - List saList = new ArrayList<>(); - - if (segmentAttributeLL.isArray()) { - Iterator elements = segmentAttributeLL.elements(); - - while (elements.hasNext()) { - String segmentAttributeValue = elements.next().fields().next().getKey(); - saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); - } - } else { - String segmentAttributeValue = segmentAttributeLL.fields().next().getKey(); - saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); - } - - attributeSet.setDisabled(saList.toArray(new J2735SegmentAttribute[0])); - } - } - - JsonNode enabled = attributes.get("enabled"); - if (enabled != null) { - JsonNode segmentAttributeLL = enabled.get("SegmentAttributeLL"); - if (segmentAttributeLL != null) { - List saList = new ArrayList<>(); - - if (segmentAttributeLL.isArray()) { - Iterator elements = segmentAttributeLL.elements(); - - while (elements.hasNext()) { - String segmentAttributeValue = elements.next().fields().next().getKey(); - saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); - } - } else { - String segmentAttributeValue = segmentAttributeLL.fields().next().getKey(); - saList.add(J2735SegmentAttribute.valueOf(segmentAttributeValue)); - } - - attributeSet.setEnabled(saList.toArray(new J2735SegmentAttribute[0])); - } - } - - JsonNode data = attributes.get("data"); - if (data != null) { - JsonNode laneDataAttribute = data.get("LaneDataAttribute"); - if (laneDataAttribute != null) { - List ldaList = new ArrayList<>(); - - if (laneDataAttribute.isArray()) { - Iterator elements = laneDataAttribute.elements(); - - while (elements.hasNext()) { - ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(elements.next())); - } - } else { - ldaList.add(LaneDataAttributeBuilder.genericLaneDataAttribute(laneDataAttribute)); - } - - attributeSet.setData(ldaList.toArray(new J2735LaneDataAttribute[0])); - } - } - - if(attributes.get("dWidth") != null) - { - attributeSet.setdWidth(attributes.get("dWidth").asInt()); - } - - if(attributes.get("dElevation") != null) - { - attributeSet.setdElevation(attributes.get("dElevation").asInt()); - } - - nodeLL.setAttributes(attributeSet); - } - return nodeLL; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java deleted file mode 100644 index 949266536..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/NodeListLLBuilder.java +++ /dev/null @@ -1,41 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeLL; -import us.dot.its.jpo.ode.plugin.j2735.J2735NodeListLL; - -public class NodeListLLBuilder { - private NodeListLLBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735NodeListLL genericNodeListLL(JsonNode nodeListNode) { - J2735NodeListLL nodeList = new J2735NodeListLL(); - - if (nodeListNode.get("nodes") != null) { - JsonNode nodeLL = nodeListNode.get("nodes").get("NodeLL"); - if (nodeLL != null) { - List nllList = new ArrayList<>(); - - if (nodeLL.isArray()) { - Iterator elements = nodeLL.elements(); - - while (elements.hasNext()) { - nllList.add(NodeLLBuilder.genericNodeLL(elements.next())); - } - } else { - nllList.add(NodeLLBuilder.genericNodeLL(nodeLL)); - } - - nodeList.setNodes(nllList.toArray(new J2735NodeLL[0])); - } - } - - return nodeList; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java deleted file mode 100644 index 5fb86c895..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/OffsetSystemBuilder.java +++ /dev/null @@ -1,39 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735Offset; -import us.dot.its.jpo.ode.plugin.j2735.J2735OffsetSystem; - -public class OffsetSystemBuilder { - private OffsetSystemBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735OffsetSystem genericOffsetSystem(JsonNode offsetSystem) { - J2735OffsetSystem genericOffsetSystem = new J2735OffsetSystem(); - - JsonNode scale = offsetSystem.get("scale"); - if (scale != null) { - genericOffsetSystem.setScale(scale.asInt()); - } - - JsonNode offset = offsetSystem.get("offset"); - if (offset != null) { - J2735Offset offsetObj = new J2735Offset(); - - JsonNode xy = offset.get("xy"); - JsonNode ll = offset.get("ll"); - - if (xy != null) { - offsetObj.setXY(NodeListXYBuilder.genericNodeListXY(xy)); - } else if (ll != null) { - offsetObj.setLL(NodeListLLBuilder.genericNodeListLL(ll)); - } - - genericOffsetSystem.setOffset(offsetObj); - } - - return genericOffsetSystem; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java deleted file mode 100644 index 26bd1a627..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TIMBuilder.java +++ /dev/null @@ -1,67 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; -import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerDataFrame; - -public class TIMBuilder { - private TIMBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735Tim genericTim(JsonNode TimMessage) { - J2735Tim genericTim = new J2735Tim(); - - JsonNode msgCnt = TimMessage.get("msgCnt"); - if (msgCnt != null) { - genericTim.setMsgCnt(msgCnt.asText()); - } - - JsonNode timeStamp = TimMessage.get("timeStamp"); - if (timeStamp != null) { - genericTim.setTimeStamp(timeStamp.asText()); - } - - JsonNode packetID = TimMessage.get("packetID"); - if (packetID != null) { - genericTim.setPacketID(packetID.asText()); - } - - // The decoder makes a null URL a literal string value of "null" when it is not specified - JsonNode urlB = TimMessage.get("urlB"); - if (urlB != null) { - String urlBValue = urlB.asText(); - if ("null".equals(urlBValue)) { - urlBValue = null; - } - genericTim.setUrlB(urlBValue); - } - - JsonNode dataFrames = TimMessage.get("dataFrames"); - if (dataFrames != null) { - JsonNode travelerDataFrame = dataFrames.get("TravelerDataFrame"); - if (travelerDataFrame != null) { - List dfList = new ArrayList<>(); - - if (travelerDataFrame.isArray()) { - Iterator elements = travelerDataFrame.elements(); - - while (elements.hasNext()) { - dfList.add(TravelerDataFrameBuilder.genericTravelerDataFrame(elements.next())); - } - } else { - dfList.add(TravelerDataFrameBuilder.genericTravelerDataFrame(travelerDataFrame)); - } - - genericTim.setDataFrames(dfList.toArray(new J2735TravelerDataFrame[0])); - } - } - - return genericTim; - } -} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java deleted file mode 100644 index 290356b0e..000000000 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerDataFrameBuilder.java +++ /dev/null @@ -1,122 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735GeographicalPath; -import us.dot.its.jpo.ode.plugin.j2735.J2735MsgId; -import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerDataFrame; -import us.dot.its.jpo.ode.plugin.j2735.J2735TravelerInfoType; - -public class TravelerDataFrameBuilder { - private TravelerDataFrameBuilder() { - throw new UnsupportedOperationException(); - } - - public static J2735TravelerDataFrame genericTravelerDataFrame(JsonNode travelerDataFrame) { - J2735TravelerDataFrame genericTravelerDataFrame = new J2735TravelerDataFrame(); - - JsonNode notUsed = travelerDataFrame.get("notUsed"); - if (notUsed != null) { - genericTravelerDataFrame.setNotUsed(notUsed.asText()); - } - - JsonNode frameType = travelerDataFrame.get("frameType"); - if (frameType != null) { - String frameTypeValue = frameType.fields().next().getKey(); - genericTravelerDataFrame.setFrameType(J2735TravelerInfoType.valueOf(frameTypeValue)); - } - - JsonNode msgId = travelerDataFrame.get("msgId"); - if (msgId != null) { - J2735MsgId msgIdObj = new J2735MsgId(); - - JsonNode furtherInfoID = msgId.get("furtherInfoID"); - if (furtherInfoID != null) { - msgIdObj.setFurtherInfoId(furtherInfoID.asText()); - } - - JsonNode roadSignID = msgId.get("roadSignID"); - if (roadSignID != null) { - msgIdObj.setRoadSignID(RoadSignIdBuilder.genericRoadSignId(roadSignID)); - } - - genericTravelerDataFrame.setMsgId(msgIdObj); - } - - JsonNode startYear = travelerDataFrame.get("startYear"); - if (startYear != null) { - genericTravelerDataFrame.setStartYear(startYear.asText()); - } - - JsonNode startTime = travelerDataFrame.get("startTime"); - if (startTime != null) { - genericTravelerDataFrame.setStartTime(startTime.asText()); - } - - JsonNode durationTime = travelerDataFrame.get("durationTime"); - if (durationTime != null) { - genericTravelerDataFrame.setDurationTime(durationTime.asText()); - } - - JsonNode priority = travelerDataFrame.get("priority"); - if (priority != null) { - genericTravelerDataFrame.setPriority(priority.asText()); - } - - JsonNode notUsed1 = travelerDataFrame.get("notUsed1"); - if (notUsed1 != null) { - genericTravelerDataFrame.setNotUsed1(notUsed1.asText()); - } - - JsonNode regions = travelerDataFrame.get("regions"); - if (regions != null) { - JsonNode geographicalPath = regions.get("GeographicalPath"); - if (geographicalPath != null) { - List gpList = new ArrayList<>(); - - if (geographicalPath.isArray()) { - Iterator elements = geographicalPath.elements(); - - while (elements.hasNext()) { - gpList.add(GeographicalPathBuilder.genericGeographicalPath(elements.next())); - } - } else { - gpList.add(GeographicalPathBuilder.genericGeographicalPath(geographicalPath)); - } - - genericTravelerDataFrame.setRegions(gpList.toArray(new J2735GeographicalPath[0])); - } - } - - JsonNode notUsed2 = travelerDataFrame.get("notUsed2"); - if (notUsed2 != null) { - genericTravelerDataFrame.setNotUsed2(notUsed2.asText()); - } - - JsonNode notUsed3 = travelerDataFrame.get("notUsed3"); - if (notUsed3 != null) { - genericTravelerDataFrame.setNotUsed3(notUsed3.asText()); - } - - JsonNode content = travelerDataFrame.get("content"); - if (content != null) { - genericTravelerDataFrame.setContent(ContentBuilder.genericContent(content)); - } - - // The decoder makes a null URL a literal string value of "null" when it is not specified - JsonNode url = travelerDataFrame.get("url"); - if (url != null) { - String urlValue = url.asText(); - if ("null".equals(urlValue)) { - urlValue = null; - } - genericTravelerDataFrame.setUrl(urlValue); - } - - return genericTravelerDataFrame; - } -} diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java deleted file mode 100644 index 04726b71e..000000000 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/J2735DirectionOfUseTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.plugin.j2735; - -import static org.junit.Assert.assertNotNull; - -import org.junit.jupiter.api.Test; - -public class J2735DirectionOfUseTest { - @Test - public void checkUnavailable() { - assertNotNull(J2735DirectionOfUse.unavailable); - } - - @Test - public void checkForward() { - assertNotNull(J2735DirectionOfUse.forward); - } - - @Test - public void checkReverse() { - assertNotNull(J2735DirectionOfUse.reverse); - } - - @Test - public void checkBoth() { - assertNotNull(J2735DirectionOfUse.both); - } -} diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java deleted file mode 100644 index d62061ee5..000000000 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TimBuilderTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package us.dot.its.jpo.ode.plugin.j2735.builders; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; - -import org.junit.jupiter.api.Test; - -import com.fasterxml.jackson.databind.JsonNode; - -import us.dot.its.jpo.ode.plugin.j2735.J2735Tim; -import us.dot.its.jpo.ode.util.XmlUtils; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; - -public class TimBuilderTest { - @Test - public void shouldTranslateTim() { - - JsonNode jsonMap = null; - try { - jsonMap = XmlUtils.toObjectNode( - "timMsgsuccessunsecuredDataMessageFrameUPERus.dot.its.jpo.ode.model.OdeAsn1Payload4d476fdf-9103-464d-88c5-5de24b9f3ef910002024-11-21T01:17:47.998Z70RSUfalse001F810A701607988D44FF260FFFD00C010F775D9B0B01C2715BDE59674A61AFFFF93F4310B021C0A007F91A54ED2088C10346A820F2C7A105164CE000000002715BDE59674A61A9388CE00021100CFA9460EE711C707B8C97B45536D12F62A75A8B8E0F329509879F9AF683B375AAC1B8AEAF70D60B3DA000C80218312D11081EEEBB36301C2715DFCC1673BB4FFFFF93F4310B021C0A007F99A54ED2088C10346A820E8CB8722083CB1E8CBC905164CE000000002715DFCC1673BB4F9388C7C0021160A5A4000E1D8955078014AA83CFCA84C1F47D5ED1521A3AF68AAD25DED055B4CF7B42AF9D7D5515A5DBFB40AE11A05EC559B908E42A8888555001A00430601C312D11080D404F775D9B00358C2614C511ABFC4ED8D5830858CC42A5B1B0023B5A84F612289408C096D7DFC084AA26FA6023C7D787B119AC3920090449C099FE4A4DF873D6B46EC2FC98916754931A4C5A500000000134E749ACB3149E209C46003C10B02211F450076888E5258B044869CC2E211098FF7108FC9E41897CCDC1704B9FCE4D42435E7023127413C78893C4DF7E848769083412036397111DCCC1B089CBA66C4435093DE2205BCA4D7089754160D73EF8A0E8441EB237825E3184501296941CB88E972102448D87064A3520F20A170A0350E408AABE263849C0B0D302157C8CC612CE3C3CA893FB247C420300172.18.0.1MessageFrame3113951608D44FF260FFFD00C01null0411472587-104651309811111111111111112024401760864050RSZ D0 45 Arch Q2300411472587-10465130985000011100000000000001274326594491070521517106782427100742958654825796649303457423414362728072821197200268125898720null0411489944-104663331211111111111111112024401760864050RSZ D0 45 Ahead Archer Q2300411489944-1046633312500000111110000000000602-10244332-34146145-34146649-30347455-25799268-257911081-212411686-106212189-68313499-15214406379114841138103761365002681230212589872013569null"); - } catch (XmlUtilsException e) { - fail("XML parsing error:" + e); - } - J2735Tim actualTim = TIMBuilder.genericTim(jsonMap.findValue("TravelerInformation")); - String actualTimString = actualTim.toString(); - String expected ="{\"msgCnt\":\"1\",\"timeStamp\":\"395160\",\"packetID\":\"8D44FF260FFFD00C01\",\"dataFrames\":[{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Arch Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1472587,\"longitude\":-104.6513098},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":true,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1274,\"lat\":326}}},{\"delta\":{\"nodeLL2\":{\"lon\":5944,\"lat\":910}}},{\"delta\":{\"nodeLL2\":{\"lon\":7052,\"lat\":1517}}},{\"delta\":{\"nodeLL3\":{\"lon\":10678,\"lat\":2427}}},{\"delta\":{\"nodeLL3\":{\"lon\":10074,\"lat\":2958}}},{\"delta\":{\"nodeLL2\":{\"lon\":6548,\"lat\":2579}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":5742,\"lat\":3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":3627,\"lat\":2807}}},{\"delta\":{\"nodeLL2\":{\"lon\":2821,\"lat\":1972}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}}]}}},{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"401760\",\"durationTime\":\"8640\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"RSZ D0 45 Ahead Archer Q23\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":41.1489944,\"longitude\":-104.6633312},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":602,\"lat\":-1024}}},{\"delta\":{\"nodeLL2\":{\"lon\":4332,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6145,\"lat\":-3414}}},{\"delta\":{\"nodeLL2\":{\"lon\":6649,\"lat\":-3034}}},{\"delta\":{\"nodeLL2\":{\"lon\":7455,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":9268,\"lat\":-2579}}},{\"delta\":{\"nodeLL3\":{\"lon\":11081,\"lat\":-2124}}},{\"delta\":{\"nodeLL3\":{\"lon\":11686,\"lat\":-1062}}},{\"delta\":{\"nodeLL3\":{\"lon\":12189,\"lat\":-683}}},{\"delta\":{\"nodeLL3\":{\"lon\":13499,\"lat\":-152}}},{\"delta\":{\"nodeLL3\":{\"lon\":14406,\"lat\":379}}},{\"delta\":{\"nodeLL3\":{\"lon\":11484,\"lat\":1138}}},{\"delta\":{\"nodeLL3\":{\"lon\":10376,\"lat\":1365}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"268\"}},{\"item\":{\"itis\":\"12302\"}},{\"item\":{\"itis\":\"12589\"}},{\"item\":{\"itis\":\"8720\"}},{\"item\":{\"itis\":\"13569\"}}]}}}]}"; - assertEquals(expected, actualTimString); - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index 9c60aed6b..3e9c440fa 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -21,9 +21,6 @@ public class OdeTimDataCreatorHelper { - public OdeTimDataCreatorHelper() { - } - public static OdeTimData createOdeTimDataFromDecoded(String consumedData) throws XmlUtilsException { ObjectNode consumed = XmlUtils.toObjectNode(consumedData); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java new file mode 100644 index 000000000..87dce220f --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java @@ -0,0 +1,42 @@ +package us.dot.its.jpo.ode.coder; + +import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import org.junit.jupiter.api.Test; + +import us.dot.its.jpo.ode.model.OdeTimData; +import us.dot.its.jpo.ode.util.XmlUtils; +import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; + +public class OdeTimDataCreatorHelperTest { + @Test + public void testCreateOdeTimDataFromDecoded() throws IOException { + String xmlFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml"; + File xmlFile = new File(xmlFilePath); + byte[] xmlData = Files.readAllBytes(xmlFile.toPath()); + String xmlString = new String(xmlData); + try { + XmlUtils.toObjectNode(xmlString); + } catch (XmlUtilsException e) { + fail("XML parsing error:" + e); + } + + String jsonFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json"; + File jsonFile = new File(jsonFilePath); + byte[] jsonData = Files.readAllBytes(jsonFile.toPath()); + String expectedJsonString = new String(jsonData); + OdeTimData timData; + try { + timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); + assertEquals(expectedJsonString, timData.toString()); + } catch (XmlUtilsException e) { + e.printStackTrace(); + } + + } +} diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json new file mode 100644 index 000000000..60efd713f --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"adb022ef-9a97-4aa3-8bab-1fde55b620a1","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-05T10:21:33.228Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424,"dwidth":162,"delevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269,"dwidth":264,"delevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247,"dwidth":245,"delevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144,"dwidth":206,"delevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181,"dwidth":414,"delevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239,"dwidth":144,"delevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453,"dwidth":-36,"delevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57,"dwidth":463,"delevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213,"dwidth":225,"delevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482,"dwidth":-31,"delevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348,"dwidth":505,"delevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml new file mode 100644 index 000000000..b03a4ba6d --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml @@ -0,0 +1,989 @@ + + + + timMsg + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + adb022ef-9a97-4aa3-8bab-1fde55b620a1 + 1 + 0 + 0 + 0 + + 2024-12-05T10:21:33.228Z + 7 + 0 + + RSU + false + + + 001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600 + 172.18.0.1 + + + MessageFrame + + + 31 + + + 82 + 345337 + 4F4354455420535452 + IA5St + + + 29 + + + + + 4F43 + + 425 + 306216 + 31001 + 2 + 1 + + + IA5 + + 38149 + 48118 + + + -567387419 + -1717691068 + 53848 + + 15175 + + + + + + + 0001000000000000 + + + 0000000001000000 + + + + + +
+ -686654332 + 1616508908 + 38736 +
+ 3832 + + + +
+ +
+
+
+ + I + + 64573 + 33281 + + + -714161321 + -1285139143 + 48475 + + 26805 + + + + + + + 0000001000000000 + + + 1 + + + + + + + -127947 + -120550 + + + + + + + + + + + + + + + + + + + + + + 101 + + + + + + 5822 + + + + + + 3017 + + + -8 + 62 + 35 + + 162 + 424 + + + + + + -998896073 + 735850714 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3453 + + + + + + 7876 + + + -82 + + + + + + 2097 + + + + 264 + -269 + + + + + + 86161 + 20207 + + + + + + + + + + + + + + + + + + + -68 + + 245 + 247 + + + + + + -172 + 525 + + + + + + + + + + + + + + 206 + 144 + + + + + + -873243 + 1464496 + + + + + + + + + + + + + + + + 58 + 137 + 1 + 25 + + 414 + 181 + + + + + + + + + + IA5 + + 7296 + 1154 + + + 29950376 + 270580409 + 16367 + + 4926 + + + + + + + 0000000001000000 + + + 0000001000000000 + + + + 26482 + +
+ 598135630 + 664850545 + 32186 +
+ 3930 + + + +
+
+
+
+ + IA5S + + 1582 + 46417 + + + -283655839 + -685153664 + 57976 + + 7235 + + + + + + + 0000000100000000 + + + 0000001000000000 + + + + + + + 581272185 + 1108489970 + 9059 + + 20085 + + + + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + -87 + 4 + -167 + + 144 + 239 + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + + + + + + 3517 + + + + -36 + -453 + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + + + + + + 60 + -95 + + 463 + 57 + + + + + + + + + + + IA5 + + 11251 + 41890 + + + 385181606 + 1670812734 + 46812 + + 16153 + + + + + + + 0000001000000000 + + + 0000000001000000 + + + + 6004 + +
+ -509239964 + 772185922 + 9413 +
+ 1224 + + + +
+
+
+
+
+ 15 + 9 + + + + + 599 + + + + + IA5S +
+ + 11 + + + + + + + 634998835 + 313588249 + 50308 + + 0000000001000000 + + + + 4F43 + + + 3481 + 305174 + 24752 + 5 + 10 + + + I + + 44107 + 63537 + + + -419185997 + -533287210 + 51107 + + 25278 + + + + + + + 0000000000001000 + + + 8 + + + + + + + 900792217 + 448269129 + + + + + + + + + + + + + + + + + + + 18 + 9 + 24 + + 225 + -213 + + + + + + 900792217 + 448269129 + + + + + + + + + + + + + + + + + + + + -109 + 83 + + -31 + -482 + + + + + + -1370 + -1581 + + + + + + + + + + + + + + + + + + + + + + + + -121 + + 505 + 348 + + + + + + + + + + IA + + 30031 + 322 + + + -454547095 + 353479827 + 59458 + + 23566 + + + + + + + 0000000000100000 + + + 0000000000000010 + + + + 24321 + +
+ -539150408 + -814772254 + 45059 +
+ 1157 + + + +
+
+
+
+ + IA5St + + 46088 + 60227 + + + -476956537 + 759386724 + 4505 + + 28846 + + + + + + + 0000000000000010 + + + 0010000000000000 + + + + 8084 + +
+ -405703383 + -508985739 + 9512 +
+ 2519 + + + +
+
+
+
+
+ 11 + 23 + + + + + I + + + + + IA5St + + + + + IA5 + + + + + IA5St +
+ + 13 + + + + + 4F43 + + 2776 + 408571 + 15957 + 5 + 6 + + + IA + + 62756 + 63693 + + + 424936826 + -1208779998 + 35858 + + 18563 + + + + + + + 0000000010000000 + + + 0010000000000000 + + + + 17158 + +
+ 442482548 + -804103995 + 43319 +
+ 1951 + + + +
+
+
+
+ + IA5S + + 51032 + 30319 + + + -559743245 + 1697199162 + 46636 + + 5901 + + + + + + + 0000000000000100 + + + 0000001000000000 + + + + 28716 + +
+ 707126893 + -77527193 + 35728 +
+ 3343 + + + +
+
+
+
+ + IA + + 23939 + 26592 + + + -328004279 + 88284632 + 45419 + + 15118 + + + + + + + 0000100000000000 + + + 1000000000000000 + + + + + +
+ 171361070 + 1462406911 + 57912 +
+ 3502 + + + +
+ +
+
+
+
+ 31 + 12 + + + + + 40721 + + + + + 36784 + + + + + IA5S + + + + + IA5 + + + + + 49435 + + + + + IA5S +
+
+
+
+
+
+
+
\ No newline at end of file From 37e5399e5bf73d75fc9088c16ff796246bcae787 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Thu, 5 Dec 2024 10:29:30 -0700 Subject: [PATCH 127/264] Add test for NodeAttributeSetLL. Fix JSON serialization of dElevation and dWidth properties. Fix OdeTimDataCreatorHelperTest data --- .../j2735/common/NodeAttributeSetXY.java | 5 +++ .../NodeAttributeSetLL.java | 5 +++ .../NodeAttributeSetLLTest.java | 38 +++++++++++++++++++ .../OdeTimDataCreatorHelper_TIM_JSON.json | 2 +- scripts/tests/udpsender_tim.py | 4 +- 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java index c8ce8ca5b..af3fd9034 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.j2735.common; +import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -13,6 +14,8 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; /** + * + * EDITED: Add @JsonProperty annotations to dWidth and dElevation * ******************************************************************************* * @@ -56,9 +59,11 @@ public class NodeAttributeSetXY extends Asn1Sequence { private LaneDataAttributeList data; @Asn1Property(tag = 4, optional = true) @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @JsonProperty("dWidth") private Offset_B10 dWidth; @Asn1Property(tag = 5, optional = true) @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @JsonProperty("dElevation") private Offset_B10 dElevation; @Asn1Property(tag = 6, optional = true) private SequenceOfRegional regional; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java index c52a2f41e..37ca7cf0d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.j2735.common.LaneDataAttributeList; import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; @@ -15,6 +16,8 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; /** + * + * EDITED: Add @JsonProperty annotations to dWidth and dElevation * ******************************************************************************* * @@ -58,9 +61,11 @@ public class NodeAttributeSetLL extends Asn1Sequence { private LaneDataAttributeList data; @Asn1Property(tag = 4, optional = true) @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @JsonProperty("dWidth") private Offset_B10 dWidth; @Asn1Property(tag = 5, optional = true) @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @JsonProperty("dElevation") private Offset_B10 dElevation; @Asn1Property(tag = 6, optional = true) private SequenceOfRegional regional; diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java new file mode 100644 index 000000000..21fd63f21 --- /dev/null +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java @@ -0,0 +1,38 @@ +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Test serializing and deserializing a NodeAttributeSetLL to and from ODE JSON + */ +public class NodeAttributeSetLLTest { + + private final static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void testDeserializeJson_dWidth_dElevation() throws JsonProcessingException { + final NodeAttributeSetLL nasll = mapper.readValue(DWITDH_DELEVATION_ONLY_JSON, NodeAttributeSetLL.class); + assertNotNull(nasll); + final long dElevation = nasll.getDElevation().getValue(); + assertEquals(424, dElevation); + final long dWidth = nasll.getDWidth().getValue(); + assertEquals(162, dWidth); + } + + @Test + public void testSerializeJson_dWidth_dElevation() throws JsonProcessingException { + final var nasll = new NodeAttributeSetLL(); + nasll.setDElevation(new Offset_B10(424L)); + nasll.setDWidth(new Offset_B10(162L)); + final String jsonResult = mapper.writeValueAsString(nasll); + assertEquals(DWITDH_DELEVATION_ONLY_JSON, jsonResult); + } + + private final static String DWITDH_DELEVATION_ONLY_JSON = """ + {"dWidth":162,"dElevation":424}"""; +} diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json index 60efd713f..0f7dd9c1f 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"adb022ef-9a97-4aa3-8bab-1fde55b620a1","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-05T10:21:33.228Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424,"dwidth":162,"delevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269,"dwidth":264,"delevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247,"dwidth":245,"delevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144,"dwidth":206,"delevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181,"dwidth":414,"delevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239,"dwidth":144,"delevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453,"dwidth":-36,"delevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57,"dwidth":463,"delevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213,"dwidth":225,"delevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482,"dwidth":-31,"delevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348,"dwidth":505,"delevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"adb022ef-9a97-4aa3-8bab-1fde55b620a1","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-05T10:21:33.228Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file diff --git a/scripts/tests/udpsender_tim.py b/scripts/tests/udpsender_tim.py index 3638e8317..1856766df 100644 --- a/scripts/tests/udpsender_tim.py +++ b/scripts/tests/udpsender_tim.py @@ -10,10 +10,10 @@ #MESSAGE = "005f498718cca69ec1a04600000100105d9b46ec5be401003a0103810040038081d4001f80d07016da410000000000000bbc2b0f775d9b0309c271431fa166ee0a27fff93f136b8205a0a107fb2ef979f4c5bfaeec97e4ad70c2fb36cd9730becdb355cc2fd2a7556b160b98b46ab98ae62c185fa55efb468d5b4000000004e2863f42cddc144ff7980040401262cdd7b809c509f5c62cdd35519c507b9062cdcee129c505cf262cdca5ff9c50432c62cdc5d3d9c502e3e62cdc13e79c501e9262cdbca2d9c5013ee62cdb80359c500e6a62cdb36299c500bc862cdaec1d9c50093c62cdaa2109c5006ea1080203091a859eeebb36006001830001aad27f4ff7580001aad355e39b5880a30029d6585009ef808332d8d9f80c3855151b38c772f765007967ec1170bcb7937f5cb880a25a52863493bcb87570dbcb5abc6bfb2faec606cfa34eb95a24790b2017366d3aabe7729e" # Complex random example (with computed lanes) -#MESSAGE = "001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240" +MESSAGE = "001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240" # Complex random example -MESSAGE = "001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A6" +#MESSAGE = "001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A6" print("UDP target IP:", UDP_IP) print("UDP target port:", UDP_PORT) From 8ec195744a40a0f4ec433d99116c67383d80afd4 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 14:12:58 -0700 Subject: [PATCH 128/264] Updated ensureComplianceWithJ2735Revision2024() in TravelerMessageFromHumanToAsnConverter to be more informative about what fields were not compliant --- ...ravelerMessageFromHumanToAsnConverter.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index b25f87a7c..19038b296 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -20,8 +20,10 @@ import java.time.Duration; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; +import java.util.ArrayList; import java.util.Iterator; +import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -1140,14 +1142,30 @@ private static String nodeOffsetPointXY(long transformedX, long transformedY) { */ public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { // Check and throw exception if old fields are found - if (dataFrame.has(SSP_MSG_CONTENT) || dataFrame.has(SSP_MSG_TYPES) || - dataFrame.has(SSP_TIM_RIGHTS) || dataFrame.has(SSP_LOCATION_RIGHTS) || - dataFrame.has(SSP_MSG_RIGHTS_1) || dataFrame.has(SSP_MSG_RIGHTS_2) || - dataFrame.has(NOT_USED) || dataFrame.has(NOT_USED_1) || - dataFrame.has(NOT_USED_2) || dataFrame.has(NOT_USED_3) || - dataFrame.has(DURATON_TIME_MISSPELLED)) { + Set nonCompliantFields = Set.of( + SSP_MSG_CONTENT, + SSP_MSG_TYPES, + SSP_LOCATION_RIGHTS, + SSP_TIM_RIGHTS, + SSP_MSG_RIGHTS_1, + SSP_MSG_RIGHTS_2, + NOT_USED, + NOT_USED_1, + NOT_USED_2, + NOT_USED_3, + DURATON_TIME_MISSPELLED + ); + ArrayList violations = new ArrayList<>(); + for (String violationName : nonCompliantFields) { + if (dataFrame.has(violationName)) { + violations.add(violationName); + } + } + if (!violations.isEmpty()) { throw new IllegalArgumentException( - "Data frame contains old fields that are not compliant with J2735 2024. Deserialization should prevent this."); + String.format( + "Data frame contains the following old fields that are not compliant with J2735 2024: [%s]. Deserialization should prevent this.", + violations)); } } From 795fef6e8d5be40d098d9939e0759fb23c861670 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 14:14:42 -0700 Subject: [PATCH 129/264] Pulled object mapper out of individual tests in TravelerDataFrameTest --- .../ode/plugin/j2735/timstorage/TravelerDataFrameTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java index aa3f1b771..ea30d3ef5 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrameTest.java @@ -9,12 +9,12 @@ import java.nio.file.Paths; class TravelerDataFrameTest { + ObjectMapper mapper = new ObjectMapper(); @Test void deserializePreJ2735_2016() throws IOException { String json = new String(Files.readAllBytes(Paths.get( "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_pre-J2735-2016.json"))); - ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); @@ -26,7 +26,6 @@ void deserializePreJ2735_2016() throws IOException { void deserializeJ2735_2016() throws IOException { String json = new String(Files.readAllBytes(Paths.get( "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2016.json"))); - ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); @@ -38,7 +37,6 @@ void deserializeJ2735_2016() throws IOException { void deserializeJ2735_2020() throws IOException { String json = new String(Files.readAllBytes(Paths.get( "src/test/resources/us/dot/its/jpo/ode/plugin/j2735/timstorage/travelerDataFrame_J2735-2020.json"))); - ObjectMapper mapper = new ObjectMapper(); TravelerDataFrame expectedFrame = getExpectedTravelerDataFrame(); TravelerDataFrame deserializedFrame = mapper.readValue(json, TravelerDataFrame.class); From b643ea6b20aee59e69efb33e384c13e0057051fb Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 14:29:00 -0700 Subject: [PATCH 130/264] Updated TravelerMessageFromHumanToAsnConverter to throw custom NoncompliantFieldsException instead of IllegalArgumentException --- ...ravelerMessageFromHumanToAsnConverter.java | 19 +++-- ...lerMessageFromHumanToAsnConverterTest.java | 69 +++++++++++-------- .../ode/traveler/TimDepositController.java | 6 +- .../traveler/TimDepositControllerTest.java | 3 +- .../ode/traveler/TimTransmogrifierTest.java | 3 +- 5 files changed, 65 insertions(+), 35 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index 19038b296..dd1dfacd0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -140,7 +140,7 @@ private TravelerMessageFromHumanToAsnConverter() { * @throws IllegalArgumentException if the JsonNode contains old fields that are no longer used */ public static void convertTravelerInputDataToEncodableTim(JsonNode tid) - throws JsonUtilsException { + throws JsonUtilsException, NoncompliantFieldsException { // msgCnt MsgCount, // timeStamp MinuteOfTheYear OPTIONAL // packetID UniqueMSGID OPTIONAL @@ -164,7 +164,8 @@ public static void convertTravelerInputDataToEncodableTim(JsonNode tid) timDataObjectNode.remove(DATAFRAMES); } - public static ObjectNode transformDataFrames(JsonNode dataFrames) throws JsonUtilsException { + public static ObjectNode transformDataFrames(JsonNode dataFrames) + throws JsonUtilsException, NoncompliantFieldsException { if (dataFrames == null) { return JsonUtils.newNode(); @@ -185,7 +186,8 @@ public static ObjectNode transformDataFrames(JsonNode dataFrames) throws JsonUti return JsonUtils.newObjectNode(TRAVELER_DATA_FRAME_STRING, replacedDataFrames); } - public static void replaceDataFrame(ObjectNode dataFrame) throws JsonUtilsException { + public static void replaceDataFrame(ObjectNode dataFrame) + throws JsonUtilsException, NoncompliantFieldsException { // INPUT ////// @@ -1140,7 +1142,8 @@ private static String nodeOffsetPointXY(long transformedX, long transformedY) { * @param dataFrame the JSON object representing the data frame to be checked * @throws IllegalArgumentException if any old fields are found */ - public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { + public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) + throws NoncompliantFieldsException { // Check and throw exception if old fields are found Set nonCompliantFields = Set.of( SSP_MSG_CONTENT, @@ -1162,11 +1165,17 @@ public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) { } } if (!violations.isEmpty()) { - throw new IllegalArgumentException( + throw new NoncompliantFieldsException( String.format( "Data frame contains the following old fields that are not compliant with J2735 2024: [%s]. Deserialization should prevent this.", violations)); } } + public static class NoncompliantFieldsException extends Exception { + public NoncompliantFieldsException(String message) { + super(message); + } + } + } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index 4c4a49a80..a9898fb3a 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -53,7 +53,8 @@ Logger getLogger(String value) { } @Test - void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException { + void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); @@ -69,7 +70,8 @@ void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtils } @Test - void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { + void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); @@ -85,7 +87,8 @@ void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException { } @Test - void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { + void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); @@ -101,7 +104,8 @@ void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException { } @Test - void testGeometryUnavailable() throws JsonUtilsException { + void testGeometryUnavailable() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -117,7 +121,8 @@ void testGeometryUnavailable() throws JsonUtilsException { } @Test - void testGeometryExitServiceForward() throws JsonUtilsException { + void testGeometryExitServiceForward() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -133,7 +138,8 @@ void testGeometryExitServiceForward() throws JsonUtilsException { } @Test - void testGeometryAdvisoryReverse() throws JsonUtilsException { + void testGeometryAdvisoryReverse() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -149,7 +155,8 @@ void testGeometryAdvisoryReverse() throws JsonUtilsException { } @Test - void testRoadSignIDWorkzone() throws JsonUtilsException { + void testRoadSignIDWorkzone() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -164,7 +171,8 @@ void testRoadSignIDWorkzone() throws JsonUtilsException { } @Test - void testGeometryBothGenericSign() throws JsonUtilsException { + void testGeometryBothGenericSign() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -180,7 +188,8 @@ void testGeometryBothGenericSign() throws JsonUtilsException { } @Test - void testPathSpeedLimit() throws JsonUtilsException { + void testPathSpeedLimit() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -253,7 +262,8 @@ void testBuildItem() { } @Test - void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -269,7 +279,8 @@ void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException { } @Test - void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -285,7 +296,8 @@ void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsExce } @Test - void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException { + void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -301,7 +313,8 @@ void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsExce } @Test - void testOldRegionWithCircle() throws JsonUtilsException { + void testOldRegionWithCircle() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -317,7 +330,8 @@ void testOldRegionWithCircle() throws JsonUtilsException { } @Test - void testOldRegionWithRegionPointSet() throws JsonUtilsException { + void testOldRegionWithRegionPointSet() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode inputTID = JsonUtils.toObjectNode( "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); @@ -333,7 +347,8 @@ void testOldRegionWithRegionPointSet() throws JsonUtilsException { } @Test - void ensureComplianceWithJ2735Revision2024_noOldFields() { + void ensureComplianceWithJ2735Revision2024_noOldFields() + throws TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("doNotUse1", 0); dataFrame.put("doNotUse2", 0); @@ -346,7 +361,7 @@ void ensureComplianceWithJ2735Revision2024_noOldFields() { void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgContent() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspMsgContent", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -355,7 +370,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgContent() { void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgTypes() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspMsgTypes", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -364,7 +379,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgTypes() { void ensureComplianceWithJ2735Revision2024_containsOldField_sspTimRights() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspTimRights", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -373,7 +388,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspTimRights() { void ensureComplianceWithJ2735Revision2024_containsOldField_sspLocationRights() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspLocationRights", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -382,7 +397,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspLocationRights() void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights1() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspMsgRights1", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -391,7 +406,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights1() { void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights2() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("sspMsgRights2", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -400,7 +415,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights2() { void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("notUsed", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -409,7 +424,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed() { void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed1() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("notUsed1", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -418,7 +433,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed1() { void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed2() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("notUsed2", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -427,7 +442,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed2() { void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed3() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("notUsed3", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -436,7 +451,7 @@ void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed3() { void ensureComplianceWithJ2735Revision2024_containsOldField_duratonTime() { ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); dataFrame.put("duratonTime", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } @@ -455,7 +470,7 @@ void ensureComplianceWithJ2735Revision2024_containsMultipleOldFields() { dataFrame.put("notUsed2", 1); dataFrame.put("notUsed3", 1); dataFrame.put("duratonTime", 1); - assertThrows(IllegalArgumentException.class, () -> { + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); }); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 07bea3cf4..24f1f1867 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -240,9 +240,13 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String errMsg = "Error converting to encodable TravelerInputData."; log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } catch (TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException e) { + String errMsg = "Non-compliant fields in TIM: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - try { + try { String xmlMsg; DdsAdvisorySituationData asd = null; if (!this.dataSigningEnabledSDW) { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 6736bb089..cf6027fca 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -119,7 +119,8 @@ public void messageWithNoRSUsOrSDWShouldReturnWarning() { public void failedObjectNodeConversionShouldReturnConvertingError( @Capturing TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) - throws JsonUtilsException { + throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { new Expectations() { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 0f9b25a14..4c5560483 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -283,7 +283,8 @@ void testConvertToXMLMessageFrame() */ @Test void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() - throws IOException, JsonUtilsException, XmlUtilsException, ParseException { + throws IOException, JsonUtilsException, XmlUtilsException, ParseException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { // prepare String timRequestContainingCircleGeometry = new String(Files.readAllBytes(Paths.get( "src/test/resources/us/dot/its/jpo/ode/traveler/timRequestContainingCircleGeometry.json"))); From 80064d62373fde3a6a710a1663894ee3bab12651 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 14:52:59 -0700 Subject: [PATCH 131/264] Addressed checkstyle warnings for TimDepositController --- .../ode/traveler/TimDepositController.java | 531 ++++++++++-------- 1 file changed, 287 insertions(+), 244 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 24f1f1867..fe4af05ce 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -1,34 +1,50 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ + package us.dot.its.jpo.ode.traveler; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.format.DateTimeParseException; +import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.*; +import us.dot.its.jpo.ode.model.OdeMsgPayload; +import us.dot.its.jpo.ode.model.OdeObject; +import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; +import us.dot.its.jpo.ode.model.OdeTimData; +import us.dot.its.jpo.ode.model.OdeTravelerInputData; +import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal.RequestVerb; @@ -45,268 +61,295 @@ import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeTimSerializer; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.format.DateTimeParseException; -import java.util.Date; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - +/** + * Controller for depositing TIMs. + */ @RestController @Slf4j public class TimDepositController { - private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); - - private static final String ERRSTR = "error"; - private static final String WARNING = "warning"; - private static final String SUCCESS = "success"; + private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); - private final Asn1CoderTopics asn1CoderTopics; - private final PojoTopics pojoTopics; - private final JsonTopics jsonTopics; + private static final String ERRSTR = "error"; + private static final String WARNING = "warning"; + private static final String SUCCESS = "success"; - private final SerialId serialIdJ2735; - private final SerialId serialIdOde; + private final Asn1CoderTopics asn1CoderTopics; + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; - private final MessageProducer stringMsgProducer; - private final MessageProducer timProducer; + private final SerialId serialIdJ2735; + private final SerialId serialIdOde; - private final boolean dataSigningEnabledSDW; + private final MessageProducer stringMsgProducer; + private final MessageProducer timProducer; - public static class TimDepositControllerException extends Exception { + private final boolean dataSigningEnabledSDW; - private static final long serialVersionUID = 1L; + /** + * Custom exception for TIM deposit controller. + */ + public static class TimDepositControllerException extends Exception { - public TimDepositControllerException(String errMsg) { - super(errMsg); - } + private static final long serialVersionUID = 1L; + public TimDepositControllerException(String errMsg) { + super(errMsg); } - @Autowired - public TimDepositController(OdeKafkaProperties odeKafkaProperties, - Asn1CoderTopics asn1CoderTopics, - PojoTopics pojoTopics, - JsonTopics jsonTopics, - TimIngestTrackerProperties ingestTrackerProperties, - SecurityServicesProperties securityServicesProperties) { - super(); - - this.asn1CoderTopics = asn1CoderTopics; - this.pojoTopics = pojoTopics; - this.jsonTopics = jsonTopics; - this.serialIdJ2735 = new SerialId(); - this.serialIdOde = new SerialId(); - - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); - this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), - null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); - - this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); - - // start the TIM ingest monitoring service if enabled - if (ingestTrackerProperties.isTrackingEnabled()) { - log.info("TIM ingest monitoring enabled."); - - ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - - scheduledExecutorService.scheduleAtFixedRate( - new TimIngestWatcher(ingestTrackerProperties.getInterval()), - ingestTrackerProperties.getInterval(), - ingestTrackerProperties.getInterval(), - java.util.concurrent.TimeUnit.SECONDS); - } else { - log.info("TIM ingest monitoring disabled."); - } + } + + /** + * Constructor. + + * @param odeKafkaProperties odeKafkaProperties + * @param asn1CoderTopics asn1CoderTopics + * @param pojoTopics pojoTopics + * @param jsonTopics jsonTopics + * @param ingestTrackerProperties ingestTrackerProperties + * @param securityServicesProperties securityServicesProperties + */ + @Autowired + public TimDepositController(OdeKafkaProperties odeKafkaProperties, + Asn1CoderTopics asn1CoderTopics, + PojoTopics pojoTopics, + JsonTopics jsonTopics, + TimIngestTrackerProperties ingestTrackerProperties, + SecurityServicesProperties securityServicesProperties) { + super(); + + this.asn1CoderTopics = asn1CoderTopics; + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + this.serialIdJ2735 = new SerialId(); + this.serialIdOde = new SerialId(); + + this.stringMsgProducer = + MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getProducer().getType(), + null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); + + this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); + + // start the TIM ingest monitoring service if enabled + if (ingestTrackerProperties.isTrackingEnabled()) { + log.info("TIM ingest monitoring enabled."); + + ScheduledExecutorService scheduledExecutorService = + Executors.newSingleThreadScheduledExecutor(); + + scheduledExecutorService.scheduleAtFixedRate( + new TimIngestWatcher(ingestTrackerProperties.getInterval()), + ingestTrackerProperties.getInterval(), + ingestTrackerProperties.getInterval(), + java.util.concurrent.TimeUnit.SECONDS); + } else { + log.info("TIM ingest monitoring disabled."); + } + } + + /** + * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST. + * + * @param jsonString TIM in JSON + * @param verb ODE.PUT or ODE.POST + * @return list of success/failures + */ + public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { + + if (null == jsonString || jsonString.isEmpty()) { + String errMsg = "Empty request."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - /** - * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST - * - * @param jsonString - * @param verb - * @return - */ - public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { - - if (null == jsonString || jsonString.isEmpty()) { - String errMsg = "Empty request."; - log.error(errMsg); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - OdeTravelerInputData odeTID; - ServiceRequest request; - try { - // Convert JSON to POJO - odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, OdeTravelerInputData.class, true); - if (odeTID == null) { - String errMsg = "Malformed or non-compliant JSON syntax."; - log.error(errMsg); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - request = odeTID.getRequest(); - if (request == null) { - throw new TimDepositControllerException("Request element is required as of version 3."); - } - - if (request.getOde() == null) { - request.setOde(new OdeInternal()); - } - - request.getOde().setVerb(verb); - - } catch (TimDepositControllerException e) { - String errMsg = "Missing or invalid argument: " + e.getMessage(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } catch (JsonUtilsException e) { - String errMsg = "Malformed or non-compliant JSON syntax."; - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - // Add metadata to message and publish to kafka - OdeTravelerInformationMessage tim = odeTID.getTim(); - OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); - OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); - - // set packetID in tim Metadata - timMetadata.setOdePacketID(tim.getPacketID()); - // set maxDurationTime in tim Metadata and set latest startDatetime in tim - // metadata - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - if (null != tim.getDataframes() && tim.getDataframes().length > 0) { - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); - try { - latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null - && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime); - } catch (ParseException e) { - log.error("Invalid dateTime parse: ", e); - } - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); - } - // Setting the SerialId to OdeBradcastTim serialId to be changed to - // J2735BroadcastTim serialId after the message has been published to - // OdeTimBrodcast topic - timMetadata.setSerialId(serialIdOde); - timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); + OdeTravelerInputData odeTID; + ServiceRequest request; + try { + // Convert JSON to POJO + odeTID = + (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, OdeTravelerInputData.class, + true); + if (odeTID == null) { + String errMsg = "Malformed or non-compliant JSON syntax."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + request = odeTID.getRequest(); + if (request == null) { + throw new TimDepositControllerException("Request element is required as of version 3."); + } + + if (request.getOde() == null) { + request.setOde(new OdeInternal()); + } + + request.getOde().setVerb(verb); + + } catch (TimDepositControllerException e) { + String errMsg = "Missing or invalid argument: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } catch (JsonUtilsException e) { + String errMsg = "Malformed or non-compliant JSON syntax."; + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + // Add metadata to message and publish to kafka + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + + // set packetID in tim Metadata + timMetadata.setOdePacketID(tim.getPacketID()); + // set maxDurationTime in tim Metadata and set latest startDatetime in tim + // metadata + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + if (null != tim.getDataframes() && tim.getDataframes().length > 0) { + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); try { - timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); - } catch (DateTimeParseException e) { - String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null + && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime); + } catch (ParseException e) { + log.error("Invalid dateTime parse: ", e); } + } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + } + // Setting the SerialId to OdeBradcastTim serialId to be changed to + // J2735BroadcastTim serialId after the message has been published to + // OdeTimBrodcast topic + timMetadata.setSerialId(serialIdOde); + timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); + + try { + timMetadata.setRecordGeneratedAt( + DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + } catch (DateTimeParseException e) { + String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } - OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); - timProducer.send(pojoTopics.getTimBroadcast(), null, odeTimData); - - String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); - stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); + OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); + timProducer.send(pojoTopics.getTimBroadcast(), null, odeTimData); - // Now that the message has been published to OdeBroadcastTim topic, it should be - // changed to J2735BroadcastTim serialId - timMetadata.setSerialId(serialIdJ2735); + String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); + stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); - // Short circuit - // If the TIM has no RSU/SNMP or SDW structures, we are done - if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { - String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams."; - log.warn(warningMsg); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); - } + // Now that the message has been published to OdeBroadcastTim topic, it should be + // changed to J2735BroadcastTim serialId + timMetadata.setSerialId(serialIdJ2735); - // Craft ASN-encodable TIM - ObjectNode encodableTid; - try { - encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - - log.debug("Encodable Traveler Information Data: {}", encodableTid); - - } catch (JsonUtilsException e) { - String errMsg = "Error converting to encodable TravelerInputData."; - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } catch (TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException e) { - String errMsg = "Non-compliant fields in TIM: " + e.getMessage(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - try { - String xmlMsg; - DdsAdvisorySituationData asd = null; - if (!this.dataSigningEnabledSDW) { - // We need to send data UNSECURED, so we should try to build the ASD as well as - // MessageFrame - asd = TimTransmogrifier.buildASD(odeTID.getRequest()); - } - xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); - log.debug("XML representation: {}", xmlMsg); - - JSONObject jsonMsg = XmlUtils.toJSONObject(xmlMsg); - - String j2735Tim = TimTransmogrifier.createOdeTimData(jsonMsg.getJSONObject(AppContext.ODE_ASN1_DATA)) - .toString(); - - stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); - - String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - // publish Broadcast TIM to a J2735 compliant topic. - stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - // publish J2735 TIM also to general un-filtered TIM topic - // with streamID as key - stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); - - serialIdOde.increment(); - serialIdJ2735.increment(); - } catch (JsonUtils.JsonUtilsException | XmlUtils.XmlUtilsException | TimTransmogrifierException e) { - String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - INGEST_MONITOR.incrementTotalMessagesReceived(); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); + // Short circuit + // If the TIM has no RSU/SNMP or SDW structures, we are done + if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { + String warningMsg = + "Warning: TIM contains no RSU, SNMP, or SDW fields." + + " Message only published to broadcast streams."; + log.warn(warningMsg); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); } - /** - * Update an already-deposited TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PutMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity putTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); + // Craft ASN-encodable TIM + ObjectNode encodableTid; + try { + encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); + + log.debug("Encodable Traveler Information Data: {}", encodableTid); + + } catch (JsonUtilsException e) { + String errMsg = "Error converting to encodable TravelerInputData."; + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } catch (TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException e) { + String errMsg = "Non-compliant fields in TIM: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - /** - * Deposit a new TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PostMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity postTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); + try { + String xmlMsg; + DdsAdvisorySituationData asd = null; + if (!this.dataSigningEnabledSDW) { + // We need to send data UNSECURED, so we should try to build the ASD as well as + // MessageFrame + asd = TimTransmogrifier.buildASD(odeTID.getRequest()); + } + xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); + log.debug("XML representation: {}", xmlMsg); + + JSONObject jsonMsg = XmlUtils.toJSONObject(xmlMsg); + + String j2735Tim = + TimTransmogrifier.createOdeTimData(jsonMsg.getJSONObject(AppContext.ODE_ASN1_DATA)) + .toString(); + + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); + + String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); + // publish Broadcast TIM to a J2735 compliant topic. + stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); + // publish J2735 TIM also to general un-filtered TIM topic + // with streamID as key + stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); + + serialIdOde.increment(); + serialIdJ2735.increment(); + } catch (JsonUtils.JsonUtilsException | XmlUtils.XmlUtilsException + | TimTransmogrifierException e) { + String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } + INGEST_MONITOR.incrementTotalMessagesReceived(); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); + } + + /** + * Update an already-deposited TIM. + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PutMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity putTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); + } + + /** + * Deposit a new TIM. + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PostMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity postTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); + } + } From dfd600fa2b5afd0c0c161b3d5a65f0e0870488f6 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 14:54:56 -0700 Subject: [PATCH 132/264] Addressed checkstyle warnings for TravelerMessageFromHumanToAsnConverterTest --- ...lerMessageFromHumanToAsnConverterTest.java | 877 +++++++++--------- 1 file changed, 442 insertions(+), 435 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java index a9898fb3a..caea580a1 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverterTest.java @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.plugin.j2735.builders; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -39,440 +40,446 @@ import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; class TravelerMessageFromHumanToAsnConverterTest { - @Mocked - Logger logger; - - @BeforeEach - void setup() { - new MockUp() { - @Mock - Logger getLogger(String value) { - return logger; - } - }; - } - - @Test - void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryUnavailable() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryExitServiceForward() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryAdvisoryReverse() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testRoadSignIDWorkzone() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testGeometryBothGenericSign() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testPathSpeedLimit() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testTranslateISOTimeStampToMinuteOfYear() { - Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T16:00:00.000Z")); - - Assertions.assertEquals(232800, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-06-11T10:00-06:00")); - - // Test for invalid timestamp - Assertions.assertEquals(527040, TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear("2018-15-44T25:66:77.999Z")); - } - - @Test - void testReplaceDataFrameTimestamp() { - String fieldName = "startDateTime"; - ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); - - startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T10:00-06:00"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); - - // Test for invalid timestamp - startDateTime = JsonUtils.newNode().put(fieldName, "2018-15-44T25:66:77.999Z"); - TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); - Assertions.assertNull(startDateTime.get("startDateTime")); - Assertions.assertEquals(0, startDateTime.get("startYear").asInt()); - Assertions.assertEquals(527040, startDateTime.get("startTime").asLong()); - } - - @Test - void testBuildItem() { - - String itisCode = "123"; - String itis = "itis"; - ObjectNode expectedItisNode = JsonUtils.newNode().put(itis, Integer.parseInt(itisCode)); - ObjectNode expecteditem = (ObjectNode) JsonUtils.newNode().set("item", expectedItisNode); - - // build ITIS code - JsonNode actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(itisCode); - Assertions.assertEquals(expecteditem, actualItem); - - // build number text - expectedItisNode.remove(itis); - expectedItisNode.put("text", itisCode); - actualItem = TravelerMessageFromHumanToAsnConverter.buildItem("'123"); - Assertions.assertEquals(expecteditem, actualItem); - - // build alphanumeric text - String test123 = "test 123"; - expectedItisNode.put("text", test123); - actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(test123); - Assertions.assertEquals(expecteditem, actualItem); - } - - @Test - void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithCircle() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void testOldRegionWithRegionPointSet() throws JsonUtilsException, - TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode inputTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); - - ObjectNode expectedTID = JsonUtils.toObjectNode( - "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); - Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); - - JSONObject timObject = new JSONObject(); - timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, - JsonUtils.toJSONObject(inputTID.toString())); - Assertions.assertNotNull(XML.toString(timObject)); - } - - @Test - void ensureComplianceWithJ2735Revision2024_noOldFields() - throws TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("doNotUse1", 0); - dataFrame.put("doNotUse2", 0); - dataFrame.put("doNotUse3", 0); - dataFrame.put("doNotUse4", 0); - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgContent() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspMsgContent", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgTypes() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspMsgTypes", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspTimRights() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspTimRights", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspLocationRights() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspLocationRights", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights1() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspMsgRights1", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights2() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspMsgRights2", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("notUsed", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed1() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("notUsed1", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed2() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("notUsed2", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed3() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("notUsed3", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsOldField_duratonTime() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("duratonTime", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } - - @Test - void ensureComplianceWithJ2735Revision2024_containsMultipleOldFields() { - ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); - dataFrame.put("sspMsgContent", 1); - dataFrame.put("sspMsgTypes", 1); - dataFrame.put("sspTimRights", 1); - dataFrame.put("sspLocationRights", 1); - dataFrame.put("sspMsgRights1", 1); - dataFrame.put("sspMsgRights2", 1); - dataFrame.put("notUsed", 1); - dataFrame.put("notUsed1", 1); - dataFrame.put("notUsed2", 1); - dataFrame.put("notUsed3", 1); - dataFrame.put("duratonTime", 1); - assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { - TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); - }); - } + @Mocked + Logger logger; + + @BeforeEach + void setup() { + new MockUp() { + @Mock + Logger getLogger(String value) { + return logger; + } + }; + } + + @Test + void testAdvisoryNodeLL() throws JsonProcessingException, IOException, JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-08-03T22:25:36.297Z\",\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataframes\":[{\"startDateTime\":\"2017-08-02T22:25:00.000Z\",\"durationTime\":1,\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.2500807\",\"longitude\":\"-111.0093847\",\"elevation\":\"2020.6969900289998\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"ll\",\"nodes\":[{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL\"},{\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL1\"},{\"nodeLong\":\"0.0008191\",\"nodeLat\":\"-0.0008192\",\"delta\":\"node-LL2\"},{\"nodeLong\":\"0.0032767\",\"nodeLat\":\"-0.0032768\",\"delta\":\"node-LL3\"},{\"nodeLong\":\"0.0131071\",\"nodeLat\":\"-0.0131072\",\"delta\":\"node-LL4\"},{\"nodeLong\":\"0.2097151\",\"nodeLat\":\"-0.2097152\",\"delta\":\"node-LL5\"},{\"nodeLong\":\"0.8388607\",\"nodeLat\":\"-0.8388608\",\"delta\":\"node-LL6\"},{\"nodeLong\":\"-111.0093847\",\"nodeLat\":\"41.2500807\",\"delta\":\"node-LatLon\"}]},\"direction\":\"0000000000001010\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.2\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL2\":{\"lat\":-8192,\"lon\":8191}}},{\"delta\":{\"node-LL3\":{\"lat\":-32768,\"lon\":32767}}},{\"delta\":{\"node-LL4\":{\"lat\":-131072,\"lon\":131071}}},{\"delta\":{\"node-LL5\":{\"lat\":-2097152,\"lon\":2097151}}},{\"delta\":{\"node-LL6\":{\"lat\":-8388608,\"lon\":8388607}}},{\"delta\":{\"node-LatLon\":{\"lat\":412500807,\"lon\":-1110093847}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testWorkzoneNodeXYWithStringLatLon() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"1\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":\"-105.047355\",\"nodeLat\":\"40.572429\",\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"workZone\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"1\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"40.573068\",\"longitude\":\"-105.049016\",\"elevation\":\"1500.8999999999999\"},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGenericSignNodeXYWithNumericLatLon() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":\"2017-10-27T18:04:43.045Z\",\"packetID\":\"3\",\"urlB\":\"null\",\"dataframes\":[{\"startDateTime\":\"2017-10-20T05:22:33.985Z\",\"durationTime\":100,\"frameType\":\"advisory\",\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":[{\"name\":\"Testing TIM\",\"regulatorID\":\"0\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"laneWidth\":\"327\",\"directionality\":\"3\",\"closedPath\":\"false\",\"description\":\"path\",\"path\":{\"scale\":\"0\",\"type\":\"xy\",\"nodes\":[{\"nodeLong\":-105.047355,\"nodeLat\":40.572429,\"delta\":\"node-LatLon\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}},{\"nodeLong\":\"-105.046844\",\"nodeLat\":\"40.572228\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04659\",\"nodeLat\":\"40.572113\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.046243\",\"nodeLat\":\"40.57191\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045936\",\"nodeLat\":\"40.571675\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045674\",\"nodeLat\":\"40.571422\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.04545\",\"nodeLat\":\"40.571131\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045235\",\"nodeLat\":\"40.570724\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045113\",\"nodeLat\":\"40.570293\",\"delta\":\"node-LatLon\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]},\"direction\":\"1111111111111111\"}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"genericSign\",\"items\":[\"7425\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":44.998459,\"longitude\":-111.040817},\"seCorner\":{\"latitude\":41.104674,\"longitude\":-104.111312}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":431644,\"packetID\":\"3\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":100,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"doNotUse1\":0,\"msgId\":\"roadSignID\",\"position\":{\"latitude\":40.573068,\"longitude\":-105.049016,\"elevation\":1500.8999999999999},\"viewAngle\":\"1111111111111111\",\"mutcd\":\"2\",\"crc\":\"0000\",\"priority\":\"5\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":32700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"xy\":{\"nodes\":{\"NodeXY\":[{\"delta\":{\"node-LatLon\":{\"lon\":-1050473550,\"lat\":405724290}},\"attributes\":{\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":41},{\"laneCrownPointLeft\":78},{\"laneCrownPointRight\":115},{\"laneAngle\":1},{\"speedLimits\":[{\"type\":{\"maxSpeedInSchoolZoneWhenChildrenArePresent\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"maxSpeedInSchoolZone\":\"EMPTY_TAG\"},\"speed\":1170},{\"type\":{\"maxSpeedInConstructionZone\":\"EMPTY_TAG\"},\"speed\":615},{\"type\":{\"vehicleMinSpeed\":\"EMPTY_TAG\"},\"speed\":1170}]}],\"dWidth\":123,\"dElevation\":234}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050468440,\"lat\":405722280}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050465900,\"lat\":405721130}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050462430,\"lat\":405719100}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050459360,\"lat\":405716750}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050456740,\"lat\":405714220}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050454500,\"lat\":405711310}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050452350,\"lat\":405707240}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050451130,\"lat\":405702930}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"direction\":\"1111111111111111\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":405730680,\"long\":-1050490160,\"elevation\":15009}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":420802,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":7425}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryUnavailable() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"unknown\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"0\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"unknown\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"unavailable\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryExitServiceForward() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"1\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"exitService\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"forward\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryAdvisoryReverse() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"roadSignage\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"2\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"advisory\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"roadSignage\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"reverse\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testRoadSignIDWorkzone() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"2\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"commercialSignage\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ {\"nodeLong\":\"0.0002047\",\"nodeLat\":\"-0.0002048\",\"delta\":\"node-LL\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":123},{\"laneCrownPointCenter\":12.3},{\"laneCrownPointLeft\":\"23.4\"},{\"laneCrownPointRight\":34.5},{\"laneAngle\":\"1.23\"},{\"speedLimits\":[{\"type\":\"2\",\"speed\":\"12.3\"},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":\"23.4\"},{\"type\":3,\"speed\":12.3},{\"type\":\"vehicleMinSpeed\",\"speed\":23.4}]}],\"dWidth\":\"1.23\",\"dElevation\":\"2.34\"}}, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"2\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"commercialSignage\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL1\":{\"lat\":-2048,\"lon\":2047}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testGeometryBothGenericSign() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}}, \"tim\": { \"msgCnt\": \"13\", \"timeStamp\": \"2017-03-13T01:07:11-05:00\", \"packetID\": \"1\", \"urlB\": \"null\", \"dataframes\": [ { \"doNotUse1\": 0, \"frameType\": \"0\", \"msgId\": \"roadSignID\", \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcd\": \"5\", \"crc\": \"0000\", \"startDateTime\": \"2017-12-01T17:47:11-05:00\", \"durationTime\": \"22\", \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"bob\", \"regulatorID\": \"23\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"direction\": \"1010101010101010\", \"description\": \"geometry\", \"geometry\": { \"direction\": \"1010101010101010\", \"extent\": \"1\", \"laneWidth\": \"33\", \"circle\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"radius\": \"15\", \"units\": \"7\" } } } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"genericSign\", \"items\": [ \"250\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"1\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"0\":\"EMPTY_TAG\"},\"msgId\":\"roadSignID\",\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcd\":\"5\",\"crc\":\"0000\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"geometry\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"laneWidth\":3300,\"circle\":{\"radius\":\"15\",\"units\":{\"mile\":\"EMPTY_TAG\"},\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"genericSign\":{\"SEQUENCE\":[{\"item\":{\"itis\":250}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testPathSpeedLimit() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\": \"1\", \"timeStamp\": \"2017-08-03T22:25:36.297Z\", \"urlB\": \"null\", \"packetID\": \"EC9C236B0000000000\", \"dataframes\": [ { \"startDateTime\": \"2017-08-02T22:25:00.000Z\", \"durationTime\": 1, \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": { \"roadSignID\": { \"position\": { \"latitude\": \"41.678473\", \"longitude\": \"-108.782775\", \"elevation\": \"917.1432\" }, \"viewAngle\": \"1010101010101010\", \"mutcdCode\": \"warning\", \"crc\": \"0000\" } }, \"priority\": \"0\", \"doNotUse2\": 0, \"regions\": [ { \"name\": \"Testing TIM\", \"regulatorID\": \"0\", \"segmentID\": \"33\", \"anchorPosition\": { \"latitude\": \"41.2500807\", \"longitude\": \"-111.0093847\", \"elevation\": \"2020.6969900289998\" }, \"laneWidth\": \"7\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": { \"scale\": \"0\", \"type\": \"ll\", \"nodes\": [ { \"nodeLong\": \"0.0031024\", \"nodeLat\": \"0.0014506\", \"delta\": \"node-LL3\",\"attributes\":{\"localNode\":[\"stopLine\",\"roundedCapStyleA\",\"roundedCapStyleB\",\"mergePoint\",\"divergePoint\",\"downstreamStopLine\",\"downstreamStartNode\",\"closedToTraffic\",\"safeIsland\",\"curbPresentAtStepOff\",\"hydrantPresent\",\"reserved\"],\"disabled\":[\"reserved\",\"doNotBlock\",\"whiteLine\",\"mergingLaneLeft\",\"mergingLaneRight\",\"curbOnLeft\",\"curbOnRight\",\"loadingzoneOnLeft\",\"loadingzoneOnRight\",\"turnOutPointOnLeft\",\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnLeft\",\"adjacentParkingOnRight\",\"adjacentBikeLaneOnLeft\"],\"data\":[{\"pathEndPointAngle\":\"123\"},{\"laneCrownPointCenter\":\"111\"},{\"laneCrownPointLeft\":\"5.5\"}],\"dWidth\":\"33\",\"dElevation\":\"500\"} }, { \"nodeLong\": \"0.0030974\", \"nodeLat\": \"0.0014568\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030983\", \"nodeLat\": \"0.0014559\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030980\", \"nodeLat\": \"0.0014563\", \"delta\": \"node-LL3\" }, { \"nodeLong\": \"0.0030982\", \"nodeLat\": \"0.0014562\", \"delta\": \"node-LL3\" } ] }, \"direction\": \"0000000000001010\" } ], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"speedLimit\", \"items\": [ \"513\" ], \"url\": \"null\" } ] }}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"1\",\"timeStamp\":309505,\"urlB\":\"null\",\"packetID\":\"EC9C236B0000000000\",\"dataFrames\":{\"TravelerDataFrame\":[{\"durationTime\":1,\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"Testing TIM\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"description\":{\"path\":{\"scale\":\"0\",\"offset\":{\"ll\":{\"nodes\":{\"NodeLL\":[{\"delta\":{\"node-LL3\":{\"lat\":14506,\"lon\":31024}}},{\"delta\":{\"node-LL3\":{\"lat\":14568,\"lon\":30974}}},{\"delta\":{\"node-LL3\":{\"lat\":14559,\"lon\":30983}}},{\"delta\":{\"node-LL3\":{\"lat\":14563,\"lon\":30980}}},{\"delta\":{\"node-LL3\":{\"lat\":14562,\"lon\":30982}}}]}}}}},\"direction\":\"0000000000001010\",\"id\":{\"region\":0,\"id\":33},\"anchor\":{\"lat\":412500807,\"long\":-1110093847,\"elevation\":20207}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":308065,\"tcontent\":{\"speedLimit\":{\"SEQUENCE\":[{\"item\":{\"itis\":513}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testTranslateISOTimeStampToMinuteOfYear() { + Assertions.assertEquals(232800, + TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear( + "2018-06-11T16:00:00.000Z")); + + Assertions.assertEquals(232800, + TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear( + "2018-06-11T10:00-06:00")); + + // Test for invalid timestamp + Assertions.assertEquals(527040, + TravelerMessageFromHumanToAsnConverter.translateISOTimeStampToMinuteOfYear( + "2018-15-44T25:66:77.999Z")); + } + + @Test + void testReplaceDataFrameTimestamp() { + String fieldName = "startDateTime"; + ObjectNode startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T16:00:00.000Z"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); + + startDateTime = JsonUtils.newNode().put(fieldName, "2018-06-11T10:00-06:00"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(2018, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(232800, startDateTime.get("startTime").asLong()); + + // Test for invalid timestamp + startDateTime = JsonUtils.newNode().put(fieldName, "2018-15-44T25:66:77.999Z"); + TravelerMessageFromHumanToAsnConverter.replaceDataFrameTimestamp(startDateTime); + Assertions.assertNull(startDateTime.get("startDateTime")); + Assertions.assertEquals(0, startDateTime.get("startYear").asInt()); + Assertions.assertEquals(527040, startDateTime.get("startTime").asLong()); + } + + @Test + void testBuildItem() { + + String itisCode = "123"; + String itis = "itis"; + ObjectNode expectedItisNode = JsonUtils.newNode().put(itis, Integer.parseInt(itisCode)); + ObjectNode expecteditem = (ObjectNode) JsonUtils.newNode().set("item", expectedItisNode); + + // build ITIS code + JsonNode actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(itisCode); + Assertions.assertEquals(expecteditem, actualItem); + + // build number text + expectedItisNode.remove(itis); + expectedItisNode.put("text", itisCode); + actualItem = TravelerMessageFromHumanToAsnConverter.buildItem("'123"); + Assertions.assertEquals(expecteditem, actualItem); + + // build alphanumeric text + String test123 = "test 123"; + expectedItisNode.put("text", test123); + actualItem = TravelerMessageFromHumanToAsnConverter.buildItem(test123); + Assertions.assertEquals(expecteditem, actualItem); + } + + @Test + void testOldRegionWithShapePointSetWithNodeList() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"nodes\":[{\"x\":\"-5.12\",\"y\":\"5.11\",\"delta\":\"node-XY\"},{\"x\":\"-10.24\",\"y\":\"10.23\",\"delta\":\"node-XY\"},{\"x\":\"-20.48\",\"y\":\"20.47\",\"delta\":\"node-XY\"},{\"x\":\"-40.96\",\"y\":\"40.95\",\"delta\":\"node-XY\"},{\"x\":\"-81.92\",\"y\":\"81.91\",\"delta\":\"node-XY\"},{\"x\":\"-327.68\",\"y\":\"327.67\",\"delta\":\"node-XY\"},{\"nodeLong\":\"-105.045087\",\"nodeLat\":\"40.569848\",\"delta\":\"node-LatLon\"}]}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":-512,\"y\":511}}},{\"delta\":{\"node-XY2\":{\"x\":-1024,\"y\":1023}}},{\"delta\":{\"node-XY3\":{\"x\":-2048,\"y\":2047}}},{\"delta\":{\"node-XY4\":{\"x\":-4096,\"y\":4095}}},{\"delta\":{\"node-XY5\":{\"x\":-8192,\"y\":8191}}},{\"delta\":{\"node-XY6\":{\"x\":-32768,\"y\":32767}}},{\"delta\":{\"node-LatLon\":{\"lon\":-1050450870,\"lat\":405698480}}}]}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithShapePointSetWithComputedLanesSmall() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"111\",\"offsetYaxis\":\"111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"small\":111},\"offsetYaxis\":{\"small\":111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithShapePointSetWithComputedLanesLarge() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"shapePointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"33\",\"directionality\":\"3\",\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":\"11111\",\"offsetYaxis\":\"11111\",\"rotateXY\":\"123.45\",\"scaleXaxis\":\"123.45\",\"scaleYaxis\":\"123.45\"}}}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"exitService\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"laneWidth\":3300,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"nodeList\":{\"computed\":{\"referenceLaneId\":\"123\",\"offsetXaxis\":{\"large\":11111},\"offsetYaxis\":{\"large\":11111},\"rotateXY\":9876,\"scaleXaxis\":469,\"scaleYaxis\":469}}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"exitService\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithCircle() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"circle\":{\"center\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"radius\":\"2048\",\"units\":\"centimeter\"}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"circle\":{\"center\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"radius\":\"2048\",\"units\":{\"centimeter\":\"EMPTY_TAG\"}}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void testOldRegionWithRegionPointSet() throws JsonUtilsException, + TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode inputTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":\"2017-03-13T01:07:11-05:00\",\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataframes\":[{\"doNotUse1\":0,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":\"warning\",\"crc\":\"0000\"}},\"startDateTime\":\"2017-12-01T17:47:11-05:00\",\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":[{\"name\":\"bob\",\"regulatorID\":\"23\",\"segmentID\":\"33\",\"anchorPosition\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"laneWidth\":\"7\",\"directionality\":\"3\",\"closedPath\":\"false\",\"direction\":\"1010101010101010\",\"description\":\"oldRegion\",\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":\"1\",\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}}],\"doNotUse4\":0,\"doNotUse3\":0,\"content\":\"advisory\",\"items\":[\"125\",\"some text\",\"250\",\"'98765\"],\"url\":\"null\"}]}}"); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(inputTID); + + ObjectNode expectedTID = JsonUtils.toObjectNode( + "{\"request\":{\"rsus\":[{\"rsuIndex\":\"10\",\"rsuTarget\":\"127.0.0.3\",\"rsuUsername\":\"v3user\",\"rsuPassword\":\"password\",\"rsuRetries\":\"1\",\"rsuTimeout\":\"1000\"}],\"snmp\":{\"rsuid\":\"00000083\",\"msgid\":\"31\",\"mode\":\"1\",\"channel\":\"178\",\"interval\":\"2\",\"deliverystart\":\"2017-06-01T17:47:11-05:00\",\"deliverystop\":\"2018-01-01T17:47:11-05:15\",\"enable\":\"1\",\"status\":\"4\"},\"sdw\":{\"ttl\":\"oneweek\",\"serviceRegion\":{\"nwCorner\":{\"latitude\":\"44.998459\",\"longitude\":\"-111.040817\"},\"seCorner\":{\"latitude\":\"41.104674\",\"longitude\":\"-104.111312\"}}}},\"tim\":{\"msgCnt\":\"13\",\"timeStamp\":102607,\"packetID\":\"EC9C236B0000000000\",\"urlB\":\"null\",\"dataFrames\":{\"TravelerDataFrame\":[{\"doNotUse1\":0,\"frameType\":{\"advisory\":\"EMPTY_TAG\"},\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171},\"viewAngle\":\"1010101010101010\",\"mutcdCode\":{\"warning\":\"EMPTY_TAG\"},\"crc\":\"0000\"}},\"durationTime\":\"22\",\"priority\":\"0\",\"doNotUse2\":0,\"regions\":{\"GeographicalPath\":[{\"name\":\"bob\",\"laneWidth\":700,\"directionality\":{\"both\":\"EMPTY_TAG\"},\"closedPath\":\"BOOLEAN_OBJECT_FALSE\",\"direction\":\"1010101010101010\",\"description\":{\"oldRegion\":{\"direction\":\"1010101010101010\",\"extent\":{\"useFor3meters\":\"EMPTY_TAG\"},\"area\":{\"regionPointSet\":{\"anchor\":{\"latitude\":\"41.678473\",\"longitude\":\"-108.782775\",\"elevation\":\"917.1432\"},\"scale\":\"0\",\"nodeList\":[{\"xOffset\":\"-0.003\",\"yOffset\":\"0.003\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.002\",\"yOffset\":\"0.002\",\"zOffset\":\"0\"},{\"xOffset\":\"-0.001\",\"yOffset\":\"0.001\",\"zOffset\":\"0\"}]}}}},\"id\":{\"region\":23,\"id\":33},\"anchor\":{\"lat\":416784730,\"long\":-1087827750,\"elevation\":9171}}]},\"doNotUse4\":0,\"doNotUse3\":0,\"url\":\"null\",\"startYear\":2017,\"startTime\":482327,\"tcontent\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":125}},{\"item\":{\"text\":\"some text\"}},{\"item\":{\"itis\":250}},{\"item\":{\"text\":\"98765\"}}]}}}]}}}"); + Assertions.assertEquals(expectedTID.toString(), inputTID.toString()); + + JSONObject timObject = new JSONObject(); + timObject.put(TravelerMessageFromHumanToAsnConverter.TRAVELER_INFORMATION, + JsonUtils.toJSONObject(inputTID.toString())); + Assertions.assertNotNull(XML.toString(timObject)); + } + + @Test + void ensureComplianceWithJ2735Revision2024_noOldFields() + throws TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("doNotUse1", 0); + dataFrame.put("doNotUse2", 0); + dataFrame.put("doNotUse3", 0); + dataFrame.put("doNotUse4", 0); + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgContent() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgContent", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgTypes() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgTypes", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspTimRights() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspTimRights", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspLocationRights() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspLocationRights", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights1() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgRights1", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_sspMsgRights2() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgRights2", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed1() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed1", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed2() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed2", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_notUsed3() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("notUsed3", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsOldField_duratonTime() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("duratonTime", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } + + @Test + void ensureComplianceWithJ2735Revision2024_containsMultipleOldFields() { + ObjectNode dataFrame = JsonNodeFactory.instance.objectNode(); + dataFrame.put("sspMsgContent", 1); + dataFrame.put("sspMsgTypes", 1); + dataFrame.put("sspTimRights", 1); + dataFrame.put("sspLocationRights", 1); + dataFrame.put("sspMsgRights1", 1); + dataFrame.put("sspMsgRights2", 1); + dataFrame.put("notUsed", 1); + dataFrame.put("notUsed1", 1); + dataFrame.put("notUsed2", 1); + dataFrame.put("notUsed3", 1); + dataFrame.put("duratonTime", 1); + assertThrows(TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException.class, () -> { + TravelerMessageFromHumanToAsnConverter.ensureComplianceWithJ2735Revision2024(dataFrame); + }); + } } From 08292e58ca0b5124edb597fee0795776ab72df8c Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 15:10:15 -0700 Subject: [PATCH 133/264] Addressed checkstyle warnings for RegulatorySpeedLimit, NodeSetXY, Nodes, Anchor, DistanceUnits, NodeOffsetPointXY, DirectionOfUse, ComputedLane, Circle, ShapePointSet & MsgId --- .../ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java index 28c5732df..8fbfee98a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegulatorySpeedLimit.java @@ -3,12 +3,12 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * The speed limit for a given section of roadway. + */ @EqualsAndHashCode(callSuper = false) public class RegulatorySpeedLimit extends Asn1Object { - /** - * - */ private static final long serialVersionUID = 1L; private SpeedLimitType type; From f46bcb6102f185679e184421bd99d1934779ae56 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 15:19:59 -0700 Subject: [PATCH 134/264] Addressed checkstyle warnings for LaneDataAttributeList, Area, RegionPointSet, NodeLL, RegionOffsets, Id, Position, RegionList, OffsetAxis, SpeedLimitType, GeometricProjection & GeographicalPath --- .../ode/plugin/j2735/timstorage/Anchor.java | 16 +- .../jpo/ode/plugin/j2735/timstorage/Area.java | 3 + .../ode/plugin/j2735/timstorage/Circle.java | 16 +- .../plugin/j2735/timstorage/ComputedLane.java | 8 +- .../j2735/timstorage/DirectionOfUse.java | 18 +- .../j2735/timstorage/DistanceUnits.java | 17 +- .../j2735/timstorage/GeographicalPath.java | 16 +- .../j2735/timstorage/GeometricProjection.java | 16 +- .../jpo/ode/plugin/j2735/timstorage/Id.java | 15 +- .../timstorage/LaneDataAttributeList.java | 13 +- .../ode/plugin/j2735/timstorage/MsgId.java | 15 +- .../ode/plugin/j2735/timstorage/NodeLL.java | 15 +- .../j2735/timstorage/NodeOffsetPointXY.java | 156 +++++++++--------- .../plugin/j2735/timstorage/NodeSetXY.java | 10 +- .../ode/plugin/j2735/timstorage/Nodes.java | 20 ++- .../plugin/j2735/timstorage/OffsetAxis.java | 15 +- .../ode/plugin/j2735/timstorage/Position.java | 16 +- .../plugin/j2735/timstorage/RegionList.java | 3 + .../j2735/timstorage/RegionOffsets.java | 37 +++-- .../j2735/timstorage/RegionPointSet.java | 3 + .../j2735/timstorage/ShapePointSet.java | 3 + .../j2735/timstorage/SpeedLimitType.java | 8 +- 22 files changed, 249 insertions(+), 190 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java index b64dfeb32..a39e085e3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Anchor.java @@ -1,27 +1,29 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Anchor point for a path. + */ @JsonPropertyOrder({"lat", "long", "elevation"}) @EqualsAndHashCode(callSuper = false) public class Anchor extends Asn1Object { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java index 897269f7b..20906205e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Area.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A geographic area. + */ @EqualsAndHashCode(callSuper = false) public class Area extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java index b73ac4f7a..afb31377e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Circle.java @@ -1,27 +1,29 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Circle. + */ @JsonPropertyOrder({"center", "radius", "units"}) @EqualsAndHashCode(callSuper = false) public class Circle extends Asn1Object { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java index 22e4e06dc..2013985f6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ComputedLane.java @@ -3,12 +3,12 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A computed lane is a lane that is derived from a reference lane by applying + * transformations to the reference lane. + */ @EqualsAndHashCode(callSuper = false) public class ComputedLane extends Asn1Object { - - /** - * - */ private static final long serialVersionUID = 1L; private int referenceLaneId; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java index 7d096a6c9..9b029dd7e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DirectionOfUse.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,10 +19,16 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * The direction of use for a given section of roadway. + */ @EqualsAndHashCode(callSuper = false) public class DirectionOfUse extends Asn1Object { private static final long serialVersionUID = 1L; + /** + * Enumeration of direction of use values. + */ public enum DirectionOfUseEnum { unavailable, // (0), -- unknown or NA, not typically used in valid expressions forward, // (1), -- direction of travel follows node ordering diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java index 07968d519..22b6d8907 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/DistanceUnits.java @@ -1,14 +1,19 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * The units of distance used in the message. + */ @EqualsAndHashCode(callSuper = false) public class DistanceUnits extends Asn1Object { private static final long serialVersionUID = 1L; + /** + * Enumeration of distance units. + */ public enum DistanceUnitsEnum { centimeter, // (0), cm2_5, // (1), -- Steps of 2.5 centimeters @@ -22,7 +27,7 @@ public enum DistanceUnitsEnum { private String centimeter; // (0), @JsonProperty("cm2-5") - private String cm2_5; // (1), -- Steps of 2.5 centimeters + private String cm2dot5; // (1), -- Steps of 2.5 centimeters private String decimeter; // (2), private String meter; // (3), private String kilometer; // (4), @@ -38,12 +43,12 @@ public void setCentimeter(String centimeter) { this.centimeter = centimeter; } - public String getCm2_5() { - return cm2_5; + public String getCm2dot5() { + return cm2dot5; } - public void setCm2_5(String cm2_5) { - this.cm2_5 = cm2_5; + public void setCm2dot5(String cm2dot5) { + this.cm2dot5 = cm2dot5; } public String getDecimeter() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java index b44636ea8..7b5195f85 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeographicalPath.java @@ -1,27 +1,29 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * GeographicalPath. + */ @JsonPropertyOrder({"name", "id", "anchor", "laneWidth", "directionality", "closedPath", "direction", "description"}) @EqualsAndHashCode(callSuper = false) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java index 5cc27604d..020eb2ac2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/GeometricProjection.java @@ -1,27 +1,29 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * GeometricProjection. + */ @JsonPropertyOrder({"direction", "extent", "laneWidth", "circle"}) @EqualsAndHashCode(callSuper = false) public class GeometricProjection extends Asn1Object { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java index 1fb923859..a8a7c7adc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Id.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Id. + */ @EqualsAndHashCode(callSuper = false) public class Id extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java index bf14a49e4..61b6b5b36 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttributeList.java @@ -1,26 +1,25 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A list of lane data attributes. + */ @EqualsAndHashCode(callSuper = false) public class LaneDataAttributeList extends Asn1Object { - /** - * - */ private static final long serialVersionUID = 1L; @JsonProperty("LaneDataAttribute") - private LaneDataAttribute LaneDataAttribute; + private LaneDataAttribute laneDataAttribute; public LaneDataAttribute getLaneDataAttribute() { - return LaneDataAttribute; + return laneDataAttribute; } public void setLaneDataAttribute(LaneDataAttribute laneDataAttribute) { - LaneDataAttribute = laneDataAttribute; + this.laneDataAttribute = laneDataAttribute; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java index 29c43a20d..a9d4352f9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/MsgId.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * MsgId. + */ @EqualsAndHashCode(callSuper = false) public class MsgId extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java index c718bb993..b0eeae309 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeLL.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * NodeLL. + */ @EqualsAndHashCode(callSuper = false) public class NodeLL extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java index d62d47bb7..6d87cd84c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java @@ -1,183 +1,185 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Node offset point in XY plane. + */ @EqualsAndHashCode(callSuper = false) public class NodeOffsetPointXY extends Asn1Object { private static final long serialVersionUID = 1L; @JsonProperty("node-XY") - private Node_XY node_XY; + private Node_XY nodeXY; @JsonProperty("node-XY1") - private Node_XY node_XY1; + private Node_XY nodeXY1; @JsonProperty("node-XY2") - private Node_XY node_XY2; + private Node_XY nodeXY2; @JsonProperty("node-XY3") - private Node_XY node_XY3; + private Node_XY nodeXY3; @JsonProperty("node-XY4") - private Node_XY node_XY4; + private Node_XY nodeXY4; @JsonProperty("node-XY5") - private Node_XY node_XY5; + private Node_XY nodeXY5; @JsonProperty("node-XY6") - private Node_XY node_XY6; + private Node_XY nodeXY6; @JsonProperty("node-LL1") - private Node_LatLon node_LL1; + private Node_LatLon nodeLL1; @JsonProperty("node-LL2") - private Node_LatLon node_LL2; + private Node_LatLon nodeLL2; @JsonProperty("node-LL3") - private Node_LatLon node_LL3; + private Node_LatLon nodeLL3; @JsonProperty("node-LL4") - private Node_LatLon node_LL4; + private Node_LatLon nodeLL4; @JsonProperty("node-LL5") - private Node_LatLon node_LL5; + private Node_LatLon nodeLL5; @JsonProperty("node-LL6") - private Node_LatLon node_LL6; + private Node_LatLon nodeLL6; @JsonProperty("node-LatLon") - private Node_LatLon node_LatLon; + private Node_LatLon nodeLatLon; - public Node_XY getNode_XY() { - return node_XY; + public Node_XY getNodeXY() { + return nodeXY; } - public void setNode_XY(Node_XY node_XY) { - this.node_XY = node_XY; + public void setNodeXY(Node_XY nodeXY) { + this.nodeXY = nodeXY; } - public Node_XY getNode_XY1() { - return node_XY1; + public Node_XY getNodeXY1() { + return nodeXY1; } - public void setNode_XY1(Node_XY node_XY1) { - this.node_XY1 = node_XY1; + public void setNodeXY1(Node_XY nodeXY1) { + this.nodeXY1 = nodeXY1; } - public Node_XY getNode_XY2() { - return node_XY2; + public Node_XY getNodeXY2() { + return nodeXY2; } - public void setNode_XY2(Node_XY node_XY2) { - this.node_XY2 = node_XY2; + public void setNodeXY2(Node_XY nodeXY2) { + this.nodeXY2 = nodeXY2; } - public Node_XY getNode_XY3() { - return node_XY3; + public Node_XY getNodeXY3() { + return nodeXY3; } - public void setNode_XY3(Node_XY node_XY3) { - this.node_XY3 = node_XY3; + public void setNodeXY3(Node_XY nodeXY3) { + this.nodeXY3 = nodeXY3; } - public Node_XY getNode_XY4() { - return node_XY4; + public Node_XY getNodeXY4() { + return nodeXY4; } - public void setNode_XY4(Node_XY node_XY4) { - this.node_XY4 = node_XY4; + public void setNodeXY4(Node_XY nodeXY4) { + this.nodeXY4 = nodeXY4; } - public Node_XY getNode_XY5() { - return node_XY5; + public Node_XY getNodeXY5() { + return nodeXY5; } - public void setNode_XY5(Node_XY node_XY5) { - this.node_XY5 = node_XY5; + public void setNodeXY5(Node_XY nodeXY5) { + this.nodeXY5 = nodeXY5; } - public Node_XY getNode_XY6() { - return node_XY6; + public Node_XY getNodeXY6() { + return nodeXY6; } - public void setNode_XY6(Node_XY node_XY6) { - this.node_XY6 = node_XY6; + public void setNodeXY6(Node_XY nodeXY6) { + this.nodeXY6 = nodeXY6; } - public Node_LatLon getNode_LL1() { - return node_LL1; + public Node_LatLon getNodeLL1() { + return nodeLL1; } - public void setNode_LL1(Node_LatLon node_LL1) { - this.node_LL1 = node_LL1; + public void setNodeLL1(Node_LatLon nodeLL1) { + this.nodeLL1 = nodeLL1; } - public Node_LatLon getNode_LL2() { - return node_LL2; + public Node_LatLon getNodeLL2() { + return nodeLL2; } - public void setNode_LL2(Node_LatLon node_LL2) { - this.node_LL2 = node_LL2; + public void setNodeLL2(Node_LatLon nodeLL2) { + this.nodeLL2 = nodeLL2; } - public Node_LatLon getNode_LL3() { - return node_LL3; + public Node_LatLon getNodeLL3() { + return nodeLL3; } - public void setNode_LL3(Node_LatLon node_LL3) { - this.node_LL3 = node_LL3; + public void setNodeLL3(Node_LatLon nodeLL3) { + this.nodeLL3 = nodeLL3; } - public Node_LatLon getNode_LL4() { - return node_LL4; + public Node_LatLon getNodeLL4() { + return nodeLL4; } - public void setNode_LL4(Node_LatLon node_LL4) { - this.node_LL4 = node_LL4; + public void setNodeLL4(Node_LatLon nodeLL4) { + this.nodeLL4 = nodeLL4; } - public Node_LatLon getNode_LL5() { - return node_LL5; + public Node_LatLon getNodeLL5() { + return nodeLL5; } - public void setNode_LL5(Node_LatLon node_LL5) { - this.node_LL5 = node_LL5; + public void setNodeLL5(Node_LatLon nodeLL5) { + this.nodeLL5 = nodeLL5; } - public Node_LatLon getNode_LL6() { - return node_LL6; + public Node_LatLon getNodeLL6() { + return nodeLL6; } - public void setNode_LL6(Node_LatLon node_LL6) { - this.node_LL6 = node_LL6; + public void setNodeLL6(Node_LatLon nodeLL6) { + this.nodeLL6 = nodeLL6; } - public Node_LatLon getNode_LatLon() { - return node_LatLon; + public Node_LatLon getNodeLatLon() { + return nodeLatLon; } - public void setNode_LatLon(Node_LatLon node_LatLon) { - this.node_LatLon = node_LatLon; + public void setNodeLatLon(Node_LatLon nodeLatLon) { + this.nodeLatLon = nodeLatLon; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java index c1e874f03..aa4c0e8cd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeSetXY.java @@ -1,23 +1,25 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A set of one or more nodes in the XY plane. + */ @EqualsAndHashCode(callSuper = false) public class NodeSetXY extends Asn1Object { private static final long serialVersionUID = 1L; - private NodeXY[] NodeXY; + private NodeXY[] nodeXY; @JsonProperty("NodeXY") public NodeXY[] getNodeXY() { - return NodeXY; + return nodeXY; } public void setNodeXY(NodeXY[] nodeXY) { - this.NodeXY = nodeXY; + this.nodeXY = nodeXY; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java index acbb56e9f..50edc1a09 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Nodes.java @@ -1,26 +1,28 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Nodes. + */ @EqualsAndHashCode(callSuper = false) public class Nodes extends Asn1Object { @@ -35,8 +37,8 @@ public NodeLL[] getNodeLL() { return nodeLL; } - public void setNodeLL(NodeLL[] NodeLL) { - this.nodeLL = NodeLL; + public void setNodeLL(NodeLL[] nodeLL) { + this.nodeLL = nodeLL; } @Override diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java index e2bebe3f1..5c273718b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetAxis.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * OffsetAxis. + */ @EqualsAndHashCode(callSuper = false) public class OffsetAxis extends Asn1Object { private static final long serialVersionUID = 7703530986729802700L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java index 696ffabce..d951ce986 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Position.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,10 +19,12 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Position given by latitude, longitude, and elevation. + */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonPropertyOrder({"lat", "llong", "elevation"}) @EqualsAndHashCode(callSuper = false) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java index ea9a7e20d..935d6b844 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionList.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A list of regions. + */ @EqualsAndHashCode(callSuper = false) public class RegionList extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java index 61d4b3ac6..489246bc2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionOffsets.java @@ -1,38 +1,45 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * The offsets of a region. + */ @EqualsAndHashCode(callSuper = false) public class RegionOffsets extends Asn1Object { private static final long serialVersionUID = 1L; - private int xOffset; - private int yOffset; - private int zOffset; + @JsonProperty("xOffset") + private int offsetX; + @JsonProperty("yOffset") + private int offsetY; + @JsonProperty("zOffset") + private int offsetZ; - public int getxOffset() { - return xOffset; + public int getOffsetX() { + return offsetX; } - public void setxOffset(int xOffset) { - this.xOffset = xOffset; + public void setOffsetX(int offsetX) { + this.offsetX = offsetX; } - public int getyOffset() { - return yOffset; + public int getOffsetY() { + return offsetY; } - public void setyOffset(int yOffset) { - this.yOffset = yOffset; + public void setOffsetY(int offsetY) { + this.offsetY = offsetY; } - public int getzOffset() { - return zOffset; + public int getOffsetZ() { + return offsetZ; } - public void setzOffset(int zOffset) { - this.zOffset = zOffset; + public void setOffsetZ(int offsetZ) { + this.offsetZ = offsetZ; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java index 94c6701b1..2f9e408d0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/RegionPointSet.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A set of one or more regions. + */ @EqualsAndHashCode(callSuper = false) public class RegionPointSet extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java index c751c1839..6bf042e82 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ShapePointSet.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A set of points in the XY plane that define a shape. + */ @EqualsAndHashCode(callSuper = false) public class ShapePointSet extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java index c4942ac4d..bc5662e68 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitType.java @@ -3,14 +3,16 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * The type of speed limit. + */ @EqualsAndHashCode(callSuper = false) public class SpeedLimitType extends Asn1Object { + private static final long serialVersionUID = 1L; /** - * + * Enumerated type for speed limit types. */ - private static final long serialVersionUID = 1L; - public enum SpeedLimitTypeEnum { unknown, //-- Speed limit type not available maxSpeedInSchoolZone, //-- Only sent when the limit is active From d6d19421924b948b9aae63daf3ab9bbb5b5b4cf5 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 15:35:12 -0700 Subject: [PATCH 135/264] Addressed checkstyle warnings for Content, Description, SpeedLimitList, NodeListLL, TravelerDataFrame, NodeListXY, FrameType, NodeXY, Regions, NodeXYAsn1Object & Offset --- .../ode/plugin/j2735/timstorage/Content.java | 15 ++++--- .../plugin/j2735/timstorage/Description.java | 15 ++++--- .../ode/plugin/j2735/timstorage/Extent.java | 6 +++ .../plugin/j2735/timstorage/FrameType.java | 18 +++++--- .../plugin/j2735/timstorage/NodeListLL.java | 15 ++++--- .../plugin/j2735/timstorage/NodeListXY.java | 3 ++ .../j2735/timstorage/NodeOffsetPointXY.java | 42 +++++++++---------- .../ode/plugin/j2735/timstorage/NodeXY.java | 15 ++++--- .../{Node_XY.java => NodeXYAsn1Object.java} | 40 ++++++++++-------- .../ode/plugin/j2735/timstorage/Offset.java | 15 ++++--- .../ode/plugin/j2735/timstorage/Regions.java | 24 ++++++----- .../j2735/timstorage/SpeedLimitList.java | 14 +++---- .../j2735/timstorage/TravelerDataFrame.java | 16 +++---- 13 files changed, 138 insertions(+), 100 deletions(-) rename jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/{Node_XY.java => NodeXYAsn1Object.java} (51%) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java index fa3afac19..7046c14fe 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Content.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Content. + */ @EqualsAndHashCode(callSuper = false) public class Content extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java index 984f31e95..569d9a83d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Description.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Description. + */ @EqualsAndHashCode(callSuper = false) public class Description extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java index a4d4a203c..75e74d079 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Extent.java @@ -3,10 +3,16 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Extent. + */ @EqualsAndHashCode(callSuper = false) public class Extent extends Asn1Object { private static final long serialVersionUID = 1L; + /** + * Enumerated values for Extent. + */ public enum ExtentEnum { useInstantlyOnly, // (0), useFor3meters, // (1), diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java index cb847eb4e..852c04cc7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/FrameType.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,11 +19,17 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * FrameType. + */ @EqualsAndHashCode(callSuper = false) public class FrameType extends Asn1Object { private static final long serialVersionUID = 1L; + /** + * Enumeration of TravelerInfoType. + */ public enum TravelerInfoType { unknown, advisory, diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java index 6c0afd3f4..152477e44 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListLL.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * NodeListLL. + */ @EqualsAndHashCode(callSuper = false) public class NodeListLL extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java index 8fb7cf1e0..3b80bec72 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeListXY.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A list of nodes in the XY plane. + */ @EqualsAndHashCode(callSuper = false) public class NodeListXY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java index 6d87cd84c..5ef9ba522 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeOffsetPointXY.java @@ -29,25 +29,25 @@ public class NodeOffsetPointXY extends Asn1Object { private static final long serialVersionUID = 1L; @JsonProperty("node-XY") - private Node_XY nodeXY; + private NodeXYAsn1Object nodeXY; @JsonProperty("node-XY1") - private Node_XY nodeXY1; + private NodeXYAsn1Object nodeXY1; @JsonProperty("node-XY2") - private Node_XY nodeXY2; + private NodeXYAsn1Object nodeXY2; @JsonProperty("node-XY3") - private Node_XY nodeXY3; + private NodeXYAsn1Object nodeXY3; @JsonProperty("node-XY4") - private Node_XY nodeXY4; + private NodeXYAsn1Object nodeXY4; @JsonProperty("node-XY5") - private Node_XY nodeXY5; + private NodeXYAsn1Object nodeXY5; @JsonProperty("node-XY6") - private Node_XY nodeXY6; + private NodeXYAsn1Object nodeXY6; @JsonProperty("node-LL1") private Node_LatLon nodeLL1; @@ -70,59 +70,59 @@ public class NodeOffsetPointXY extends Asn1Object { @JsonProperty("node-LatLon") private Node_LatLon nodeLatLon; - public Node_XY getNodeXY() { + public NodeXYAsn1Object getNodeXY() { return nodeXY; } - public void setNodeXY(Node_XY nodeXY) { + public void setNodeXY(NodeXYAsn1Object nodeXY) { this.nodeXY = nodeXY; } - public Node_XY getNodeXY1() { + public NodeXYAsn1Object getNodeXY1() { return nodeXY1; } - public void setNodeXY1(Node_XY nodeXY1) { + public void setNodeXY1(NodeXYAsn1Object nodeXY1) { this.nodeXY1 = nodeXY1; } - public Node_XY getNodeXY2() { + public NodeXYAsn1Object getNodeXY2() { return nodeXY2; } - public void setNodeXY2(Node_XY nodeXY2) { + public void setNodeXY2(NodeXYAsn1Object nodeXY2) { this.nodeXY2 = nodeXY2; } - public Node_XY getNodeXY3() { + public NodeXYAsn1Object getNodeXY3() { return nodeXY3; } - public void setNodeXY3(Node_XY nodeXY3) { + public void setNodeXY3(NodeXYAsn1Object nodeXY3) { this.nodeXY3 = nodeXY3; } - public Node_XY getNodeXY4() { + public NodeXYAsn1Object getNodeXY4() { return nodeXY4; } - public void setNodeXY4(Node_XY nodeXY4) { + public void setNodeXY4(NodeXYAsn1Object nodeXY4) { this.nodeXY4 = nodeXY4; } - public Node_XY getNodeXY5() { + public NodeXYAsn1Object getNodeXY5() { return nodeXY5; } - public void setNodeXY5(Node_XY nodeXY5) { + public void setNodeXY5(NodeXYAsn1Object nodeXY5) { this.nodeXY5 = nodeXY5; } - public Node_XY getNodeXY6() { + public NodeXYAsn1Object getNodeXY6() { return nodeXY6; } - public void setNodeXY6(Node_XY nodeXY6) { + public void setNodeXY6(NodeXYAsn1Object nodeXY6) { this.nodeXY6 = nodeXY6; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java index 04c9960e9..350dcb02a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXY.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * NodeXY. + */ @EqualsAndHashCode(callSuper = false) public class NodeXY extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXYAsn1Object.java similarity index 51% rename from jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java rename to jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXYAsn1Object.java index 1fc69223d..838009d88 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Node_XY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeXYAsn1Object.java @@ -1,46 +1,52 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Node_XY. + */ @EqualsAndHashCode(callSuper = false) -public class Node_XY extends Asn1Object { +public class NodeXYAsn1Object extends Asn1Object { private static final long serialVersionUID = 1L; - private String x; + @JsonProperty("x") + private String xpos; - private String y; + @JsonProperty("y") + private String ypos; - public String getX() { - return x; + public String getXpos() { + return xpos; } - public void setX(String x) { - this.x = x; + public void setXpos(String xpos) { + this.xpos = xpos; } - public String getY() { - return y; + public String getYpos() { + return ypos; } - public void setY(String y) { - this.y = y; + public void setYpos(String ypos) { + this.ypos = ypos; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java index 99c9d6450..02b729bee 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Offset.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Offset. + */ @EqualsAndHashCode(callSuper = false) public class Offset extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java index f5e6e06c9..915cb66e7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/Regions.java @@ -1,37 +1,39 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Regions. + */ @EqualsAndHashCode(callSuper = false) public class Regions extends Asn1Object { private static final long serialVersionUID = 1L; - private GeographicalPath[] GeographicalPath; - @JsonProperty("GeographicalPath") + private GeographicalPath[] geographicalPath; + public GeographicalPath[] getGeographicalPath() { - return GeographicalPath; + return geographicalPath; } public void setGeographicalPath(GeographicalPath[] geographicalPath) { - this.GeographicalPath = geographicalPath; + this.geographicalPath = geographicalPath; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java index 275160df6..6d214c5fd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/SpeedLimitList.java @@ -1,27 +1,25 @@ package us.dot.its.jpo.ode.plugin.j2735.timstorage; import com.fasterxml.jackson.annotation.JsonProperty; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * A list of speed limits. + */ @EqualsAndHashCode(callSuper = false) public class SpeedLimitList extends Asn1Object { - - /** - * - */ private static final long serialVersionUID = 1L; @JsonProperty("RegulatorySpeedLimit") - private RegulatorySpeedLimit[] RegulatorySpeedLimit; + private RegulatorySpeedLimit[] regulatorySpeedLimit; public RegulatorySpeedLimit[] getRegulatorySpeedLimit() { - return RegulatorySpeedLimit; + return regulatorySpeedLimit; } public void setRegulatorySpeedLimit(RegulatorySpeedLimit[] regulatorySpeedLimit) { - RegulatorySpeedLimit = regulatorySpeedLimit; + this.regulatorySpeedLimit = regulatorySpeedLimit; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java index 860be692d..eaa3dfc9a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/TravelerDataFrame.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -20,10 +20,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; - import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * Traveler data frame. + */ @JsonPropertyOrder({"doNotUse1", "frameType", "msgId", "startYear", "startTime", "durationTime", "priority", "doNotUse2", "regions", "doNotUse3", "doNotUse4", "tcontent", "url"}) From 3abe4e3151a491d34a749ac00656d85e5137827a Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Thu, 5 Dec 2024 15:42:42 -0700 Subject: [PATCH 136/264] use KafkaType instead of Producer Type so that confluent is configured correctly (#130) --- .../its/jpo/ode/SerializableMessageProducerPool.java | 2 +- .../us/dot/its/jpo/ode/coder/ByteArrayPublisher.java | 2 +- .../its/jpo/ode/coder/FileAsn1CodecPublisher.java | 2 +- .../jpo/ode/services/asn1/Asn1CommandManager.java | 2 +- .../jpo/ode/services/asn1/Asn1DecodedDataRouter.java | 12 ++++++------ .../jpo/ode/services/asn1/Asn1EncodedDataRouter.java | 2 +- .../ode/services/asn1/message/Asn1DecodeBSMJSON.java | 2 +- .../ode/services/asn1/message/Asn1DecodePSMJSON.java | 2 +- .../services/asn1/message/Asn1DecodeSPATJSON.java | 2 +- .../ode/services/asn1/message/Asn1DecodeSRMJSON.java | 2 +- .../ode/services/asn1/message/Asn1DecodeSSMJSON.java | 2 +- .../ode/services/asn1/message/Asn1DecodeTIMJSON.java | 2 +- .../its/jpo/ode/services/json/ToJsonConverter.java | 2 +- .../its/jpo/ode/traveler/TimDepositController.java | 4 ++-- .../java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 2 +- .../dot/its/jpo/ode/udp/generic/GenericReceiver.java | 2 +- .../java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java | 2 +- .../us/dot/its/jpo/ode/udp/spat/SpatReceiver.java | 2 +- .../java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java | 2 +- .../java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 2 +- .../java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java | 2 +- 21 files changed, 27 insertions(+), 27 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java index ce1bef40a..980c29fbc 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/SerializableMessageProducerPool.java @@ -39,7 +39,7 @@ public SerializableMessageProducerPool(OdeKafkaProperties odeKafkaProperties) { super(); this.odeKafkaProperties = odeKafkaProperties; this.brokers = odeKafkaProperties.getBrokers(); - this.type = odeKafkaProperties.getProducer().getType(); + this.type = odeKafkaProperties.getKafkaType(); this.partitionerClass = odeKafkaProperties.getProducer().getPartitionerClass(); init(); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java index 9e9ca9e95..c2e0f8cb0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/ByteArrayPublisher.java @@ -26,7 +26,7 @@ public class ByteArrayPublisher implements MessagePublisher { public ByteArrayPublisher(OdeKafkaProperties odeKafkaProperties) { this.bytesProducer = MessageProducer.defaultByteArrayMessageProducer( - odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java index 9d40bee16..3823c6047 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/FileAsn1CodecPublisher.java @@ -42,7 +42,7 @@ public FileAsn1CodecPublisherException(String string, Exception e) { public FileAsn1CodecPublisher(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, RawEncodedJsonTopics rawEncodedJsonTopics) { StringPublisher messagePub = new StringPublisher(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.codecPublisher = new LogFileToAsn1CodecPublisher(messagePub, jsonTopics, rawEncodedJsonTopics); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java index fa2af8bde..2e3db752d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1CommandManager.java @@ -83,7 +83,7 @@ public Asn1CommandManager(OdeKafkaProperties odeKafkaProperties, SDXDepositorTop this.rsuDepositor = new RsuDepositor(rsuProperties, securityServicesProperties.getIsRsuSigningEnabled()); this.rsuDepositor.start(); this.stringMessageProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.depositTopic = sdxDepositorTopics.getInput(); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index 5189f40f8..c5772cba4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -50,24 +50,24 @@ public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics p this.pojoTopics = pojoTopics; this.jsonTopics = jsonTopics; this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), null, OdeBsmSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 57b7a9aee..7a4d2193f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -79,7 +79,7 @@ public Asn1EncodedDataRouter(OdeKafkaProperties odeKafkaProperties, this.jsonTopics = jsonTopics; this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.asn1CommandManager = new Asn1CommandManager(odeKafkaProperties, sdxDepositorTopics, rsuProperties, securityServicesProperties); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java index f510fdd6c..30125100a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodeBSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeBSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.BSM.getStartFlag() ); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java index 515afa619..607dda70e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodePSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodePSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.PSM.getStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java index a3582b4f8..0b0c528de 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodeSPATJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSPATJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.SPAT.getStartFlag() ); } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java index 56bca2426..eba4cf5a4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodeSRMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSRMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.SRM.getStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java index fe2c9485c..2ab4d44e9 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodeSSMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeSSMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.SSM.getStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java index 6e86509cf..39556f794 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSON.java @@ -22,7 +22,7 @@ public class Asn1DecodeTIMJSON extends AbstractAsn1DecodeMessageJSON { public Asn1DecodeTIMJSON(OdeKafkaProperties odeKafkaProperties, String publishTopic) { super( publishTopic, - new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()), + new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()), SupportedMessageType.TIM.getStartFlag() );} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java index ca2a9f42c..d45d91d46 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/json/ToJsonConverter.java @@ -30,7 +30,7 @@ public class ToJsonConverter extends AbstractSubPubTransformer(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), + odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index 236ea68b5..2773fbc4b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -20,7 +20,7 @@ public BsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index e5130debd..86658d093 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -22,7 +22,7 @@ public class GenericReceiver extends AbstractUdpReceiverPublisher { public GenericReceiver(UDPReceiverProperties.ReceiverProperties props, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { super(props.getReceiverPort(), props.getBufferSize()); - this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.rawEncodedJsonTopics = rawEncodedJsonTopics; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index 32ce0d8d6..c0ed9c7c4 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -20,7 +20,7 @@ public PsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index 61c5d101b..78f24ecad 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -20,7 +20,7 @@ public SpatReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index e06d3a4aa..dba63b8c1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -20,7 +20,7 @@ public SrmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index 326f2ce5d..d4dd8e164 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -20,7 +20,7 @@ public SsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 0bfb0b9d0..96b599222 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -20,7 +20,7 @@ public TimReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); this.publishTopic = publishTopic; - this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getProducer().getType(), odeKafkaProperties.getDisabledTopics()); + this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); } @Override From 3ce69319f53f692cda1b963838f936890c50a2f8 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Thu, 5 Dec 2024 15:52:02 -0700 Subject: [PATCH 137/264] Addressed checkstyle warnings for NodeAttributeSetXY, ValidRegion, OffsetSystem, LaneDataAttribute & TravelerMessageFromHumanToAsnConverter --- ...ravelerMessageFromHumanToAsnConverter.java | 199 ++++++++++++++---- .../j2735/timstorage/LaneDataAttribute.java | 7 +- .../j2735/timstorage/NodeAttributeSetXY.java | 51 +++-- .../plugin/j2735/timstorage/OffsetSystem.java | 15 +- .../plugin/j2735/timstorage/ValidRegion.java | 3 + 5 files changed, 200 insertions(+), 75 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java index dd1dfacd0..2315df19f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/builders/TravelerMessageFromHumanToAsnConverter.java @@ -1,36 +1,33 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.builders; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import java.math.BigDecimal; import java.time.Duration; import java.time.ZonedDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Iterator; - import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ArrayNode; -import com.fasterxml.jackson.databind.node.ObjectNode; - import us.dot.its.jpo.ode.plugin.j2735.DsrcPosition3D; import us.dot.its.jpo.ode.plugin.j2735.timstorage.DirectionOfUse.DirectionOfUseEnum; import us.dot.its.jpo.ode.plugin.j2735.timstorage.DistanceUnits.DistanceUnitsEnum; @@ -41,6 +38,10 @@ import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; +/** + * This class is used to convert a JsonNode representing an OdeTravelerInputData object to a format + * that can be encoded by the asn1_codec submodule. + */ public class TravelerMessageFromHumanToAsnConverter { private static final String SPEED = "speed"; @@ -133,7 +134,8 @@ private TravelerMessageFromHumanToAsnConverter() { } /** - * Converts a JsonNode representing an OdeTravelerInputData object to a format that can be encoded by the asn1_codec submodule. + * Converts a JsonNode representing an OdeTravelerInputData object to a format + * that can be encoded by the asn1_codec submodule. * * @param tid TravelerInputData object serialized as a JsonNode * @throws JsonUtilsException if there is an issue converting the JsonNode @@ -164,6 +166,14 @@ public static void convertTravelerInputDataToEncodableTim(JsonNode tid) timDataObjectNode.remove(DATAFRAMES); } + /** + * Transforms the dataFrames field. + * + * @param dataFrames JsonNode representing the dataFrames field + * @return ObjectNode representing the transformed dataFrames field + * @throws JsonUtilsException if there is an issue converting the JsonNode + * @throws NoncompliantFieldsException if the JsonNode contains old fields that are no longer used + */ public static ObjectNode transformDataFrames(JsonNode dataFrames) throws JsonUtilsException, NoncompliantFieldsException { @@ -186,6 +196,13 @@ public static ObjectNode transformDataFrames(JsonNode dataFrames) return JsonUtils.newObjectNode(TRAVELER_DATA_FRAME_STRING, replacedDataFrames); } + /** + * Replaces a data frame. + * + * @param dataFrame ObjectNode representing the data frame + * @throws JsonUtilsException if there is an issue converting the JsonNode + * @throws NoncompliantFieldsException if the JsonNode contains old fields that are no longer used + */ public static void replaceDataFrame(ObjectNode dataFrame) throws JsonUtilsException, NoncompliantFieldsException { @@ -249,14 +266,21 @@ public static void replaceDataFrame(ObjectNode dataFrame) replaceMsgId(dataFrame); } + /** + * Translates ISO timestamp to minute of year. + * + * @param isoTime ISO timestamp + * @return minute of year + */ public static long translateISOTimeStampToMinuteOfYear(String isoTime) { int startYear = 0; int startMinute = 527040; try { - ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(isoTime); - startYear = zDateTime.getYear(); + ZonedDateTime zonedDateTime = DateTimeUtils.isoDateTime(isoTime); + startYear = zonedDateTime.getYear(); startMinute = - (int) Duration.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), zDateTime) + (int) Duration.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, + 0, 0, 0), zonedDateTime) .toMinutes(); } catch (Exception e) { // NOSONAR logger.error("Failed to parse datetime {}, defaulting to unknown value {}", isoTime, @@ -266,6 +290,11 @@ public static long translateISOTimeStampToMinuteOfYear(String isoTime) { return startMinute; } + /** + * Replaces the data frame timestamp. + * + * @param dataFrame ObjectNode representing the data frame + */ public static void replaceDataFrameTimestamp(ObjectNode dataFrame) { // EXPECTED INPUT: @@ -281,11 +310,11 @@ public static void replaceDataFrameTimestamp(ObjectNode dataFrame) { int startMinute = 527040; String startDateTime = dataFrame.get(START_DATE_TIME).asText(); try { - ZonedDateTime zDateTime = DateTimeUtils.isoDateTime(startDateTime); - startYear = zDateTime.getYear(); + ZonedDateTime zonedDateTime = DateTimeUtils.isoDateTime(startDateTime); + startYear = zonedDateTime.getYear(); startMinute = (int) ChronoUnit.MINUTES.between(DateTimeUtils.isoDateTime(startYear, 1, 1, 0, 0, 0, 0), - zDateTime); + zonedDateTime); } catch (Exception e) { logger.error("Failed to startDateTime {}, defaulting to unknown value {}.", startDateTime, startMinute); @@ -296,6 +325,11 @@ public static void replaceDataFrameTimestamp(ObjectNode dataFrame) { dataFrame.remove(START_DATE_TIME); } + /** + * Replaces content. + * + * @param dataFrame ObjectNode representing the data frame + */ public static void replaceContent(ObjectNode dataFrame) { // EXPECTED OUTPUT: @@ -347,6 +381,12 @@ public static void replaceContent(ObjectNode dataFrame) { dataFrame.remove("content"); } + /** + * Builds an item. + * + * @param itemStr String representing the item + * @return JsonNode representing the item + */ public static JsonNode buildItem(String itemStr) { JsonNode item = null; // check to see if it is a itis code or text @@ -365,6 +405,11 @@ public static JsonNode buildItem(String itemStr) { return item; } + /** + * Replaces msg id. + * + * @param dataFrame ObjectNode representing the data frame + */ public static void replaceMsgId(ObjectNode dataFrame) { // @@ -402,6 +447,13 @@ public static void replaceMsgId(ObjectNode dataFrame) { } } + /** + * Transforms regions. + * + * @param regions JsonNode representing the regions + * @return ObjectNode representing the transformed regions + * @throws JsonUtilsException if there is an issue converting the JsonNode + */ public static ObjectNode transformRegions(JsonNode regions) throws JsonUtilsException { ArrayNode replacedRegions = JsonUtils.newNode().arrayNode(); @@ -418,6 +470,12 @@ public static ObjectNode transformRegions(JsonNode regions) throws JsonUtilsExce return JsonUtils.newObjectNode(GEOGRAPHICAL_PATH_STRING, replacedRegions); } + /** + * Replaces a region. + * + * @param region ObjectNode representing the region + * @throws JsonUtilsException if there is an issue converting the JsonNode + */ public static void replaceRegion(ObjectNode region) throws JsonUtilsException { //// EXPECTED INPUT: @@ -623,7 +681,6 @@ private static ObjectNode transformNodeLL(JsonNode oldNode) { Long transformedLong = null; ObjectNode innerNode = JsonUtils.newNode(); - ObjectNode deltaNode = (ObjectNode) JsonUtils.newNode().set(DELTA, innerNode); ObjectNode latLong = JsonUtils.newNode(); String deltaText = delta.asText(); if (deltaText.startsWith("node-LL")) { @@ -639,7 +696,7 @@ private static ObjectNode transformNodeLL(JsonNode oldNode) { innerNode.set(deltaText, latLong); latLong.put(LAT, transformedLat).put(LON, transformedLong); - + ObjectNode deltaNode = JsonUtils.newNode().set(DELTA, innerNode); return deltaNode; } @@ -654,38 +711,38 @@ private static ObjectNode transformNodeLL(JsonNode oldNode) { private static String nodeOffsetPointLL(long transformedLat, long transformedLon) { long transformedLatabs = Math.abs(transformedLat); long transformedLonabs = Math.abs(transformedLon); - if (((transformedLatabs & (-1 << 11)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 11)) == 0)) + if (((transformedLatabs & (-1 << 11)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 11)) == 0)) && (transformedLonabs & (-1 << 11)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 11)) == 0))) { // 11 bit value return "node-LL1"; - } else if (((transformedLatabs & (-1 << 13)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 13)) == 0)) + } else if (((transformedLatabs & (-1 << 13)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 13)) == 0)) && (transformedLonabs & (-1 << 13)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 13)) == 0))) { // 13 bit value return "node-LL2"; - } else if (((transformedLatabs & (-1 << 15)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 15)) == 0)) + } else if (((transformedLatabs & (-1 << 15)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 15)) == 0)) && (transformedLonabs & (-1 << 15)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 15)) == 0))) { // 15 bit value return "node-LL3"; - } else if (((transformedLatabs & (-1 << 17)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 17)) == 0)) + } else if (((transformedLatabs & (-1 << 17)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 17)) == 0)) && (transformedLonabs & (-1 << 17)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 17)) == 0))) { // 17 bit value return "node-LL4"; - } else if (((transformedLatabs & (-1 << 21)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 21)) == 0)) + } else if (((transformedLatabs & (-1 << 21)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 21)) == 0)) && (transformedLonabs & (-1 << 21)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 21)) == 0))) { // 21 bit value return "node-LL5"; - } else if (((transformedLatabs & (-1 << 23)) == 0 || - (transformedLat < 0 && (transformedLatabs ^ (1 << 23)) == 0)) + } else if (((transformedLatabs & (-1 << 23)) == 0 + || (transformedLat < 0 && (transformedLatabs ^ (1 << 23)) == 0)) && (transformedLonabs & (-1 << 23)) == 0 || (transformedLon < 0 && ((transformedLonabs ^ (1 << 23)) == 0))) { // 23 bit value @@ -698,6 +755,11 @@ private static String nodeOffsetPointLL(long transformedLat, long transformedLon } + /** + * Replaces geometry. + * + * @param geometry ObjectNode representing the geometry + */ public static void replaceGeometry(ObjectNode geometry) { // direction HeadingSlice @@ -719,6 +781,11 @@ public static void replaceGeometry(ObjectNode geometry) { replaceCircle(geometry.get(CIRCLE)); } + /** + * Replaces old region. + * + * @param oldRegion ObjectNode representing the old region + */ public static void replaceOldRegion(ObjectNode oldRegion) { // old region == ValidRegion @@ -734,6 +801,11 @@ public static void replaceOldRegion(ObjectNode oldRegion) { replaceArea(oldRegion.get("area")); } + /** + * Replaces area. + * + * @param area JsonNode representing the area + */ public static void replaceArea(JsonNode area) { // area contains one of: @@ -774,6 +846,11 @@ private static void replaceRegionPointSet(JsonNode regionPointSet) { // regionList is good as is and does not need replacement (required) } + /** + * Replaces circle. + * + * @param circle JsonNode representing the circle + */ public static void replaceCircle(JsonNode circle) { // Circle ::= SEQUENCE @@ -808,6 +885,11 @@ public static void replaceCircle(JsonNode circle) { } } + /** + * Replaces shape point set. + * + * @param shapePointSet JsonNode representing the shape point set + */ public static void replaceShapePointSet(JsonNode shapePointSet) { // shape point set contains: // anchor @@ -853,6 +935,11 @@ public static void replaceShapePointSet(JsonNode shapePointSet) { } } + /** + * Replaces computed lane. + * + * @param jsonNode JsonNode representing the computed lane + */ public static void replaceComputedLane(JsonNode jsonNode) { ObjectNode updatedNode = (ObjectNode) jsonNode; @@ -889,6 +976,12 @@ public static void replaceComputedLane(JsonNode jsonNode) { } } + /** + * Replaces scale. + * + * @param updatedNode ObjectNode representing the updated node + * @param scale String representing the scale + */ public static void replaceScale(ObjectNode updatedNode, String scale) { if (updatedNode.has(scale)) { int scaleX = updatedNode.get(scale).asInt(); @@ -902,6 +995,12 @@ public static void replaceScale(ObjectNode updatedNode, String scale) { } } + /** + * Transforms node set XY. + * + * @param inputNodeList JsonNode representing the input node list + * @return ArrayNode representing the transformed node list + */ public static ArrayNode transformNodeSetXY(JsonNode inputNodeList) { //// EXPECTED INPUT: @@ -929,6 +1028,12 @@ public static ArrayNode transformNodeSetXY(JsonNode inputNodeList) { return outputNodeList; } + /** + * Transformed a NodeXY. + * + * @param oldNode JsonNode representing the old node + * @return ObjectNode representing the transformed node + */ public static JsonNode transformNodeXY(JsonNode oldNode) { // nodexy contains: @@ -990,6 +1095,11 @@ private static ArrayNode transformLaneDataAttributeList(JsonNode laneDataAttribu return updatedLaneDataAttributeList; } + /** + * Replaces lane data attribute. + * + * @param oldNode JsonNode representing the old node + */ public static void replaceLaneDataAttribute(JsonNode oldNode) { // choice between 1 of the following: // pathEndPointAngle DeltaAngle @@ -1054,6 +1164,12 @@ private static void replaceRegulatorySpeedLimit(JsonNode regulatorySpeedLimitNod } + /** + * Transformed node offset point XY. + * + * @param oldNode JsonNode representing the old node + * @return ObjectNode representing the transformed node + */ public static ObjectNode transformNodeOffsetPointXY(JsonNode oldNode) { //// EXPECTED INPUT: // @@ -1078,10 +1194,10 @@ public static ObjectNode transformNodeOffsetPointXY(JsonNode oldNode) { ObjectNode deltaNode = JsonUtils.newNode(); String deltaText = delta.asText(); if (deltaText.startsWith(NODE_XY)) { - BigDecimal xOffset = JsonUtils.decimalValue(oldNode.get(X)); - BigDecimal yOffset = JsonUtils.decimalValue(oldNode.get(Y)); - Long transformedX = OffsetXyBuilder.offsetXy(xOffset); - Long transformedY = OffsetXyBuilder.offsetXy(yOffset); + BigDecimal offsetX = JsonUtils.decimalValue(oldNode.get(X)); + BigDecimal offsetY = JsonUtils.decimalValue(oldNode.get(Y)); + Long transformedX = OffsetXyBuilder.offsetXy(offsetX); + Long transformedY = OffsetXyBuilder.offsetXy(offsetY); ObjectNode xy = JsonUtils.newNode().put(X, transformedX).put(Y, transformedY); if (deltaText.equals(NODE_XY)) { innerNode.set(nodeOffsetPointXY(transformedX, transformedY), xy); @@ -1137,7 +1253,8 @@ private static String nodeOffsetPointXY(long transformedX, long transformedY) { } /** - * Ensures compliance with the J2735 2024 standard by checking for old fields in the given data frame. + * Ensures compliance with the J2735 2024 standard by checking + * for old fields in the given data frame. * * @param dataFrame the JSON object representing the data frame to be checked * @throws IllegalArgumentException if any old fields are found @@ -1167,11 +1284,15 @@ public static void ensureComplianceWithJ2735Revision2024(ObjectNode dataFrame) if (!violations.isEmpty()) { throw new NoncompliantFieldsException( String.format( - "Data frame contains the following old fields that are not compliant with J2735 2024: [%s]. Deserialization should prevent this.", + "Data frame contains the following old fields that are not compliant with " + + "J2735 2024: [%s]. Deserialization should prevent this.", violations)); } } + /** + * Exception thrown when noncompliant fields are found in the data frame. + */ public static class NoncompliantFieldsException extends Exception { public NoncompliantFieldsException(String message) { super(message); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java index 3042037b9..d18e5a680 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/LaneDataAttribute.java @@ -3,12 +3,11 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * LaneDataAttribute. + */ @EqualsAndHashCode(callSuper = false) public class LaneDataAttribute extends Asn1Object { - - /** - * - */ private static final long serialVersionUID = 1L; //-- adjusts final point/width slant diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java index 5abfcf453..aa5c62652 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/NodeAttributeSetXY.java @@ -3,36 +3,35 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * NodeAttributeSetXY. + */ @EqualsAndHashCode(callSuper = false) public class NodeAttributeSetXY extends Asn1Object { - - /** - * - */ private static final long serialVersionUID = 1L; -// localNode NodeAttributeXYList OPTIONAL, -// -- Attribute states which pertain to this node point -// disabled SegmentAttributeXYList OPTIONAL, -// -- Attribute states which are disabled at this node point -// enabled SegmentAttributeXYList OPTIONAL, -// -- Attribute states which are enabled at this node point -// -- and which remain enabled until disabled or the lane ends -// data LaneDataAttributeList OPTIONAL, -// -- Attributes which require an additional data values -// -- some of these are local to the node point, while others -// -- persist with the provided values until changed -// -- and this is indicated in each entry -// dWidth Offset-B10 OPTIONAL, -// -- A value added to the current lane width -// -- at this node and from this node onwards, in 1cm steps -// -- lane width between nodes are a linear taper between pts -// -- the value of zero shall not be sent here -// dElevation Offset-B10 OPTIONAL, -// -- A value added to the current Elevation -// -- at this node from this node onwards, in 10cm steps -// -- elevations between nodes are a linear taper between pts -// -- the value of zero shall not be sent here + // localNode NodeAttributeXYList OPTIONAL, + // -- Attribute states which pertain to this node point + // disabled SegmentAttributeXYList OPTIONAL, + // -- Attribute states which are disabled at this node point + // enabled SegmentAttributeXYList OPTIONAL, + // -- Attribute states which are enabled at this node point + // -- and which remain enabled until disabled or the lane ends + // data LaneDataAttributeList OPTIONAL, + // -- Attributes which require an additional data values + // -- some of these are local to the node point, while others + // -- persist with the provided values until changed + // -- and this is indicated in each entry + // dWidth Offset-B10 OPTIONAL, + // -- A value added to the current lane width + // -- at this node and from this node onwards, in 1cm steps + // -- lane width between nodes are a linear taper between pts + // -- the value of zero shall not be sent here + // dElevation Offset-B10 OPTIONAL, + // -- A value added to the current Elevation + // -- at this node from this node onwards, in 10cm steps + // -- elevations between nodes are a linear taper between pts + // -- the value of zero shall not be sent here private LaneDataAttributeList data; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java index 864a21a78..7f922641e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/OffsetSystem.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735.timstorage; @@ -19,6 +19,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * OffsetSystem. + */ @EqualsAndHashCode(callSuper = false) public class OffsetSystem extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java index c47b36c47..28c319a29 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/timstorage/ValidRegion.java @@ -3,6 +3,9 @@ import lombok.EqualsAndHashCode; import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +/** + * ValidRegion. + */ @EqualsAndHashCode(callSuper = false) public class ValidRegion extends Asn1Object { private static final long serialVersionUID = 1L; From f676a6b517cfe720c373049d9085a2c6749c339b Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:35:29 -0700 Subject: [PATCH 138/264] Code styling changes to appease the code styling lords --- .../us/dot/its/jpo/ode/util/XmlUtils.java | 330 +-- .../serialization/BitStringDeserializer.java | 52 +- .../serialization/BitstringSerializer.java | 43 +- .../serialization/BooleanDeserializer.java | 61 +- .../serialization/BooleanSerializer.java | 38 +- .../CharacterStringSerializer.java | 23 +- .../serialization/EnumeratedDeserializer.java | 75 +- .../serialization/EnumeratedSerializer.java | 74 +- .../serialization/IntegerDeserializer.java | 59 +- .../NestedSequenceOfDeserializer.java | 77 +- .../NestedSequenceOfSerializer.java | 78 +- .../serialization/OpenTypeDeserializer.java | 72 +- .../serialization/OpenTypeSerializer.java | 53 +- .../ParameterizedTypeDeserializer.java | 87 +- .../SequenceOfEnumeratedDeserializer.java | 84 +- .../serialization/SerializationUtil.java | 21 +- .../jpo/ode/plugin/types/Asn1Bitstring.java | 258 ++- .../its/jpo/ode/plugin/types/Asn1Boolean.java | 72 +- .../ode/plugin/types/Asn1CharacterString.java | 67 +- .../its/jpo/ode/plugin/types/Asn1Choice.java | 98 +- .../jpo/ode/plugin/types/Asn1Enumerated.java | 13 +- .../its/jpo/ode/plugin/types/Asn1Integer.java | 100 +- .../jpo/ode/plugin/types/Asn1OctetString.java | 11 +- .../jpo/ode/plugin/types/Asn1Sequence.java | 51 +- .../jpo/ode/plugin/types/Asn1SequenceOf.java | 71 +- .../its/jpo/ode/plugin/types/IA5String.java | 8 +- .../its/jpo/ode/plugin/types/UnknownType.java | 1 + .../ode/coder/OdeTimDataCreatorHelper.java | 97 +- .../ode/traveler/TimDepositController.java | 517 +++-- .../OdeTimDataCreatorHelper_TIM_XER.xml | 1974 ++++++++--------- 30 files changed, 2372 insertions(+), 2193 deletions(-) diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java index 5e0341fd9..03b007a4d 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java @@ -26,170 +26,170 @@ import com.fasterxml.jackson.dataformat.xml.XmlMapper.Builder; public class XmlUtils { - public static class XmlUtilsException extends Exception { - - private static final long serialVersionUID = 1L; - - public XmlUtilsException(String string) { - super(string); - } - - public XmlUtilsException(String string, Exception e) { - super(string, e); - } - - } - - private XmlMapper xmlMapper = new XmlMapper(); - private static XmlMapper staticXmlMapper = new XmlMapper(); - - static { - var builder = new Builder(staticXmlMapper); - builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - builder.defaultUseWrapper(true); - staticXmlMapper = builder.build(); - } - - public XmlUtils() { - super(); - var builder = new Builder(xmlMapper); - builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - builder.defaultUseWrapper(true); - xmlMapper = builder.build(); - } - - public String toXml(Object o) throws JsonProcessingException { - String xml = xmlMapper.writeValueAsString(o); - return xml; - } - - // public static String toXml(Object o) throws XmlUtilsException { - // try { - // JSONObject root = new JSONObject(); - // JSONObject object = new JSONObject(o); - // root.put(o.getClass().getSimpleName(), object); - // return XML.toString(root); - // } catch (JSONException e) { - // throw new XmlUtilsException("Error encoding object to XML", e); - // } - // } - - public Object fromXml(String xml, Class clazz) throws XmlUtilsException { - try { - return xmlMapper.readValue(xml, clazz); - } catch (Exception e) { - throw new XmlUtilsException("Error decoding " + xml + " to " + clazz.getName(), e); - } - } - - /** - * Embeds the arrayNode into an ObjectNode with the given childKey. By default a - * JSON array such as {"parent":[1, 2, 3,]} will be converted to: - * 123. - * This is not often desired as there is no paren object to encompass the array. - * By calling this method given childKey = "child" and arrayNode = [1, 2, 3,], - * method will return {"parent":{"child":[1, 2, 3,]}} which as a result will be - * encoded to - * 123. - * Which is a more representative of the JSON ObjectNode. - * - * @param childKey: The key to be given to the child array object - * @param arrayNode: The array node to be embedded in a ObjectNode - * @return OBjectNode representation of the given arrayNode redy to be converted - * to XML - */ - public static ObjectNode createEmbeddedJsonArrayForXmlConversion(String childKey, JsonNode arrayNode) { - ObjectNode childNode = staticXmlMapper.createObjectNode(); - childNode.set(childKey, arrayNode); - return childNode; - } - - public static String findXmlContentString(String xml, String tagName) { - // Construct the start and end tag strings - String startTag = "<" + tagName + ">"; - String endTag = ""; - - // Find the start index of the start tag - int startIndex = xml.indexOf(startTag); - if (startIndex == -1) { - // Tag not found - return null; - } - - // Find the end index of the end tag, after the start tag - int endIndex = xml.indexOf(endTag, startIndex); - if (endIndex == -1) { - // End tag not found - return null; - } - - // Add the length of the end tag to get the complete end index - endIndex += endTag.length(); - - return xml.substring(startIndex, endIndex); - } - - public static String toXmlStatic(Object o) throws XmlUtilsException { - String xml; - try { - xml = staticXmlMapper.writeValueAsString(o); - } catch (Exception e) { - throw new XmlUtilsException("Error encoding object to XML", e); - } - return xml; - } - - public static Object fromXmlS(String xml, Class clazz) throws XmlUtilsException { - try { - return staticXmlMapper.readValue(xml, clazz); - } catch (Exception e) { - throw new XmlUtilsException("Error decoding " + xml + " to " + clazz.getName(), e); - } - } - - public static ObjectNode toObjectNode(String xml) throws XmlUtilsException { - try { - JSONObject jsonObject = XML.toJSONObject(xml, true); - String jsonString = jsonObject.toString(); - return JsonUtils.toObjectNode(jsonString); - - /* - * Due to issues with XmlMapper converting "xml arrays" to a valid DOM - * collection we could not use it in this context. Hence the above workaround - * was adopted. See: - * https://github.com/FasterXML/jackson-dataformat-xml/issues/187 - * https://github.com/FasterXML/jackson-dataformat-xml/issues/205 - */ - // return (ObjectNode) staticXmlMapper.readTree(xml); - } catch (Exception e) { - throw new XmlUtilsException("Error decoding " + xml + "to ObjectNode", e); - } - } - - public static JSONObject toJSONObject(String xml) throws XmlUtilsException { - try { - return XML.toJSONObject(xml, true); - } catch (Exception e) { - throw new XmlUtilsException("Error decoding " + xml + "to JSONObject", e); - } - } - - public static JsonNode getJsonNode(String tree, String fieldName) throws XmlUtilsException { - JsonNode jsonNode; - try { - jsonNode = staticXmlMapper.readTree(tree); - } catch (Exception e) { - throw new XmlUtilsException("Error getting field name " + fieldName + " from " + tree, e); - } - return jsonNode.get(fieldName); - } - - public XmlMapper getXmlMapper() { - return xmlMapper; - } - - public static XmlMapper getStaticXmlMapper() { - return staticXmlMapper; - } + public static class XmlUtilsException extends Exception { + + private static final long serialVersionUID = 1L; + + public XmlUtilsException(String string) { + super(string); + } + + public XmlUtilsException(String string, Exception e) { + super(string, e); + } + + } + + private XmlMapper xmlMapper = new XmlMapper(); + private static XmlMapper staticXmlMapper = new XmlMapper(); + + static { + var builder = new Builder(staticXmlMapper); + builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + builder.defaultUseWrapper(true); + staticXmlMapper = builder.build(); + } + + public XmlUtils() { + super(); + var builder = new Builder(xmlMapper); + builder.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + builder.defaultUseWrapper(true); + xmlMapper = builder.build(); + } + + public String toXml(Object o) throws JsonProcessingException { + String xml = xmlMapper.writeValueAsString(o); + return xml; + } + + // public static String toXml(Object o) throws XmlUtilsException { + // try { + // JSONObject root = new JSONObject(); + // JSONObject object = new JSONObject(o); + // root.put(o.getClass().getSimpleName(), object); + // return XML.toString(root); + // } catch (JSONException e) { + // throw new XmlUtilsException("Error encoding object to XML", e); + // } + // } + + public Object fromXml(String xml, Class clazz) throws XmlUtilsException { + try { + return xmlMapper.readValue(xml, clazz); + } catch (Exception e) { + throw new XmlUtilsException("Error decoding " + xml + " to " + clazz.getName(), e); + } + } + + /** + * Embeds the arrayNode into an ObjectNode with the given childKey. By default a + * JSON array such as {"parent":[1, 2, 3,]} will be converted to: + * 123. + * This is not often desired as there is no paren object to encompass the array. + * By calling this method given childKey = "child" and arrayNode = [1, 2, 3,], + * method will return {"parent":{"child":[1, 2, 3,]}} which as a result will be + * encoded to + * 123. + * Which is a more representative of the JSON ObjectNode. + * + * @param childKey: The key to be given to the child array object + * @param arrayNode: The array node to be embedded in a ObjectNode + * @return OBjectNode representation of the given arrayNode redy to be converted + * to XML + */ + public static ObjectNode createEmbeddedJsonArrayForXmlConversion(String childKey, JsonNode arrayNode) { + ObjectNode childNode = staticXmlMapper.createObjectNode(); + childNode.set(childKey, arrayNode); + return childNode; + } + + public static String findXmlContentString(String xml, String tagName) { + // Construct the start and end tag strings + String startTag = "<" + tagName + ">"; + String endTag = ""; + + // Find the start index of the start tag + int startIndex = xml.indexOf(startTag); + if (startIndex == -1) { + // Tag not found + return null; + } + + // Find the end index of the end tag, after the start tag + int endIndex = xml.indexOf(endTag, startIndex); + if (endIndex == -1) { + // End tag not found + return null; + } + + // Add the length of the end tag to get the complete end index + endIndex += endTag.length(); + + return xml.substring(startIndex, endIndex); + } + + public static String toXmlStatic(Object o) throws XmlUtilsException { + String xml; + try { + xml = staticXmlMapper.writeValueAsString(o); + } catch (Exception e) { + throw new XmlUtilsException("Error encoding object to XML", e); + } + return xml; + } + + public static Object fromXmlS(String xml, Class clazz) throws XmlUtilsException { + try { + return staticXmlMapper.readValue(xml, clazz); + } catch (Exception e) { + throw new XmlUtilsException("Error decoding " + xml + " to " + clazz.getName(), e); + } + } + + public static ObjectNode toObjectNode(String xml) throws XmlUtilsException { + try { + JSONObject jsonObject = XML.toJSONObject(xml, true); + String jsonString = jsonObject.toString(); + return JsonUtils.toObjectNode(jsonString); + + /* + * Due to issues with XmlMapper converting "xml arrays" to a valid DOM + * collection we could not use it in this context. Hence the above workaround + * was adopted. See: + * https://github.com/FasterXML/jackson-dataformat-xml/issues/187 + * https://github.com/FasterXML/jackson-dataformat-xml/issues/205 + */ + // return (ObjectNode) staticXmlMapper.readTree(xml); + } catch (Exception e) { + throw new XmlUtilsException("Error decoding " + xml + "to ObjectNode", e); + } + } + + public static JSONObject toJSONObject(String xml) throws XmlUtilsException { + try { + return XML.toJSONObject(xml, true); + } catch (Exception e) { + throw new XmlUtilsException("Error decoding " + xml + "to JSONObject", e); + } + } + + public static JsonNode getJsonNode(String tree, String fieldName) throws XmlUtilsException { + JsonNode jsonNode; + try { + jsonNode = staticXmlMapper.readTree(tree); + } catch (Exception e) { + throw new XmlUtilsException("Error getting field name " + fieldName + " from " + tree, e); + } + return jsonNode.get(fieldName); + } + + public XmlMapper getXmlMapper() { + return xmlMapper; + } + + public static XmlMapper getStaticXmlMapper() { + return staticXmlMapper; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java index b90f4fee0..21b3a13ae 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitStringDeserializer.java @@ -1,47 +1,49 @@ package us.dot.its.jpo.ode.plugin.serialization; -import com.fasterxml.jackson.core.JsonToken; -import com.fasterxml.jackson.core.type.TypeReference; -import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.dataformat.xml.XmlMapper; - import java.io.IOException; import java.util.Map; +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; /** * Deserialize an ASN.1 Bitstring from XER or JER. + * *

Note that this deserializer expects ODE JSON, not standard JER. - * @param The bitstring type + * + * @param The bitstring type. * @author Ivan Yourshaw */ public abstract class BitStringDeserializer extends StdDeserializer { - protected abstract T construct(); + protected abstract T construct(); - protected BitStringDeserializer(Class valueClass) { - super(valueClass); - } + protected BitStringDeserializer(Class valueClass) { + super(valueClass); + } - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - T bitstring = construct(); - if (jsonParser.getCodec() instanceof XmlMapper) { - // XML: binary - String str = jsonParser.getText(); - bitstring.fromBinaryString(str); - } else { - // ODE JSON dialect: read verbose map - TypeReference> boolMapType = new TypeReference<>() {}; - Map map = jsonParser.readValueAs(boolMapType); - for (var keyValue : map.entrySet()) { - bitstring.set(keyValue.getKey(), keyValue.getValue()); - } - } - return bitstring; + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T bitstring = construct(); + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML: binary + String str = jsonParser.getText(); + bitstring.fromBinaryString(str); + } else { + // ODE JSON dialect: read verbose map + TypeReference> boolMapType = new TypeReference<>() { + }; + Map map = jsonParser.readValueAs(boolMapType); + for (var keyValue : map.entrySet()) { + bitstring.set(keyValue.getKey(), keyValue.getValue()); + } } + return bitstring; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java index 122cb1fa2..b86c73dc4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BitstringSerializer.java @@ -1,39 +1,40 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; - import java.io.IOException; -import java.util.LinkedHashMap; +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; /** * Serializer for ASN.1 Bitstring types to XER or JER + * *

Note that this serializer writes ODE JSON, not standard JER. + * * @author Ivan Yourshaw */ public class BitstringSerializer extends StdSerializer { - protected BitstringSerializer() { - super(Asn1Bitstring.class); - } + protected BitstringSerializer() { + super(Asn1Bitstring.class); + } - @Override - public void serialize(Asn1Bitstring asn1Bitstring, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - if (serializerProvider instanceof XmlSerializerProvider) { - // XER serializes bitstrings as binary strings - jsonGenerator.writeString(asn1Bitstring.binaryString()); - } else { - // ODE JSON dialect serializes bitstrings as verbose maps - jsonGenerator.writeStartObject(); - for (int i = 0; i < asn1Bitstring.size(); i++) { - String name = asn1Bitstring.name(i); - boolean isSet = asn1Bitstring.get(i); - jsonGenerator.writeBooleanField(name, isSet); - } - jsonGenerator.writeEndObject(); - } + @Override + public void serialize(Asn1Bitstring asn1Bitstring, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // XER serializes bitstrings as binary strings + jsonGenerator.writeString(asn1Bitstring.binaryString()); + } else { + // ODE JSON dialect serializes bitstrings as verbose maps + jsonGenerator.writeStartObject(); + for (int i = 0; i < asn1Bitstring.size(); i++) { + String name = asn1Bitstring.name(i); + boolean isSet = asn1Bitstring.get(i); + jsonGenerator.writeBooleanField(name, isSet); + } + jsonGenerator.writeEndObject(); } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java index 05e37dbb0..a8ad54e6d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanDeserializer.java @@ -1,45 +1,50 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.dataformat.xml.XmlMapper; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; -@SuppressWarnings({"unchecked", "rawtypes"}) +/** + * Deserializer for ASN.1 Boolean types to XER or JER + * + * @author Ivan Yourshaw + */ +@SuppressWarnings({ "unchecked" }) public class BooleanDeserializer extends StdDeserializer { - protected Asn1Boolean construct() { - return new Asn1Boolean(); - } + protected Asn1Boolean construct() { + return new Asn1Boolean(); + } - public BooleanDeserializer() { - super(Asn1Boolean.class); - } + public BooleanDeserializer() { + super(Asn1Boolean.class); + } - protected BooleanDeserializer(Class valueType) { - super(Asn1Boolean.class); - } + protected BooleanDeserializer(Class valueType) { + super(Asn1Boolean.class); + } - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - Asn1Boolean result = construct(); - if (jsonParser.getCodec() instanceof XmlMapper) { - // XML: unwrap empty element - TreeNode node = jsonParser.getCodec().readTree(jsonParser); - var iterator = node.fieldNames(); - if (iterator.hasNext()) { - String str = node.fieldNames().next(); - result.setValue(Boolean.parseBoolean(str)); - } - } else { - // JSON - result.setValue(jsonParser.getBooleanValue()); - } - return (T)result; + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + Asn1Boolean result = construct(); + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML: unwrap empty element + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + var iterator = node.fieldNames(); + if (iterator.hasNext()) { + String str = node.fieldNames().next(); + result.setValue(Boolean.parseBoolean(str)); + } + } else { + // JSON + result.setValue(jsonParser.getBooleanValue()); } + return (T) result; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java index 35fe77d62..a4e3b9100 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/BooleanSerializer.java @@ -1,29 +1,35 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; +/** + * Serializer for ASN.1 Boolean types to XER or JER + * + * @author Ivan Yourshaw + */ public class BooleanSerializer extends StdSerializer { - protected BooleanSerializer() { - super(Asn1Boolean.class); - } + protected BooleanSerializer() { + super(Asn1Boolean.class); + } - @Override - public void serialize(Asn1Boolean asn1Boolean, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - if (serializerProvider instanceof XmlSerializerProvider) { - // XER uses and for booleans - jsonGenerator.writeStartObject(); - jsonGenerator.writeRaw(String.format("<%s/>", asn1Boolean.getValue())); - jsonGenerator.writeEndObject(); - } else { - // JER - jsonGenerator.writeBoolean(asn1Boolean.getValue()); - } + @Override + public void serialize(Asn1Boolean asn1Boolean, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) + throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // XER uses and for booleans + jsonGenerator.writeStartObject(); + jsonGenerator.writeRaw(String.format("<%s/>", asn1Boolean.getValue())); + jsonGenerator.writeEndObject(); + } else { + // JER + jsonGenerator.writeBoolean(asn1Boolean.getValue()); } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java index 7d34858b4..532aa387c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/CharacterStringSerializer.java @@ -1,20 +1,25 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1CharacterString; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1CharacterString; +/** + * Serializer for ASN.1 character string types to XER or JER + * + * @author Ivan Yourshaw + */ public class CharacterStringSerializer extends StdSerializer { - protected CharacterStringSerializer() { - super(Asn1CharacterString.class); - } + protected CharacterStringSerializer() { + super(Asn1CharacterString.class); + } - @Override - public void serialize(Asn1CharacterString asn1CharacterString, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - jsonGenerator.writeString(asn1CharacterString.getValue()); - } + @Override + public void serialize(Asn1CharacterString asn1CharacterString, JsonGenerator jsonGenerator, + SerializerProvider serializerProvider) throws IOException { + jsonGenerator.writeString(asn1CharacterString.getValue()); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java index 524feb68c..bcb07ac83 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedDeserializer.java @@ -1,48 +1,55 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.dataformat.xml.XmlMapper; - import java.io.IOException; import java.util.Objects; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -public abstract class EnumeratedDeserializer & Asn1Enumerated> extends StdDeserializer { - - protected abstract T[] listEnumValues(); - - protected EnumeratedDeserializer(Class valueClass) { - super(valueClass); +/** + * Base class for ENUMERATED value deserializers to produce both XER and JER. + * + * @param The ENUMERATED type + * @author Ivan Yourshaw + */ +public abstract class EnumeratedDeserializer & Asn1Enumerated> + extends StdDeserializer { + + protected abstract T[] listEnumValues(); + + protected EnumeratedDeserializer(Class valueClass) { + super(valueClass); + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + String name = null; + if (jsonParser.getCodec() instanceof XmlMapper) { + // XML + // The enum in BASIC-XER is an empty element, so Jackson thinks it's an object + // with a key + // of that name with no value + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + var iterator = node.fieldNames(); + if (iterator.hasNext()) { + name = node.fieldNames().next(); + } + } else { + // JSON + // Behaves normally: The enum name is the text + name = jsonParser.getText(); } - - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - String name = null; - if (jsonParser.getCodec() instanceof XmlMapper) { - // XML - // The enum in BASIC-XER is an empty element, so Jackson thinks it's an object with a key - // of that name with no value - TreeNode node = jsonParser.getCodec().readTree(jsonParser); - var iterator = node.fieldNames(); - if (iterator.hasNext()) { - name = node.fieldNames().next(); - } - } else { - // JSON - // Behaves normally: The enum name is the text - name = jsonParser.getText(); - } - for (T enumValue : listEnumValues()) { - if (Objects.equals(enumValue.getName(), name)) { - return enumValue; - } - } - - - return null; + for (T enumValue : listEnumValues()) { + if (Objects.equals(enumValue.getName(), name)) { + return enumValue; + } } + + return null; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java index 013cd53d5..dd314cff1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/EnumeratedSerializer.java @@ -1,53 +1,53 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; /** - * Base class for ENUMERATED value serializers to produce both XER and JER + * Base class for ENUMERATED value serializers to produce both XER and JER. + * * @param The ENUMERATED type - * TODO: this doesn't need to be generic * @author Ivan Yourshaw */ -@SuppressWarnings({"unchecked", "rawtypes"}) +@SuppressWarnings({ "rawtypes" }) public class EnumeratedSerializer extends StdSerializer { - - protected EnumeratedSerializer(Class t) { - super(t); - } - - @Override - public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - if (serializerProvider instanceof XmlSerializerProvider) { - jsonGenerator.writeStartObject(); - - // - // BASIC-XER's weird way of writing enums. - // - // Ref. ITU-T X.693 (02/2021) Sec. 8.3.7 which says: - // - // The "XMLEnumeratedValue" specified in Rec. ITU-T X.680 | ISO/IEC 8824-1, 20.8, shall only be - // "EmptyElementEnumerated" - // - // and ITU-T X.680 (02/2021) Sec. 20.8 which says: - // - // EmptyElementEnumerated ::= "<" & identifier "/>" - // - jsonGenerator.writeRaw(String.format("<%s/>", t.getName())); - - jsonGenerator.writeEndObject(); - } else { - // - // JER: Just write the enum value as a string like a normal person. - // Does not handle TEXT encoding instructions per X.697 sec 22.2 - // - jsonGenerator.writeString(t.getName()); - } + protected EnumeratedSerializer(Class t) { + super(t); + } + + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + jsonGenerator.writeStartObject(); + + // + // BASIC-XER's weird way of writing enums. + // + // Ref. ITU-T X.693 (02/2021) Sec. 8.3.7 which says: + // + // The "XMLEnumeratedValue" specified in Rec. ITU-T X.680 | ISO/IEC 8824-1, + // 20.8, shall only be + // "EmptyElementEnumerated" + // + // and ITU-T X.680 (02/2021) Sec. 20.8 which says: + // + // EmptyElementEnumerated ::= "<" & identifier "/>" + // + jsonGenerator.writeRaw(String.format("<%s/>", t.getName())); + + jsonGenerator.writeEndObject(); + } else { + // + // JER: Just write the enum value as a string like a normal person. + // Does not handle TEXT encoding instructions per X.697 sec 22.2 + // + jsonGenerator.writeString(t.getName()); } + } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java index 5ccf5f343..72b4639d5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java @@ -1,6 +1,5 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; @@ -9,36 +8,44 @@ import com.fasterxml.jackson.databind.node.NumericNode; import com.fasterxml.jackson.databind.node.TextNode; import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; +/** + * Base class for INTEGER value deserializers to produce both XER and JER. + * + * @param The INTEGER type + * @author Ivan Yourshaw + */ public abstract class IntegerDeserializer extends StdDeserializer { - protected final Class thisClass; - protected abstract T construct(); + protected final Class thisClass; - protected IntegerDeserializer(Class vc) { - super(vc); - this.thisClass = vc; - } + protected abstract T construct(); + + protected IntegerDeserializer(Class vc) { + super(vc); + this.thisClass = vc; + } - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - T result = null; - if (jsonParser instanceof FromXmlParser xmlParser) { - result = construct(); - TreeNode node = xmlParser.getCodec().readTree(xmlParser); - if (node instanceof NumericNode numNode) { - result.setValue(numNode.longValue()); - } else if (node instanceof TextNode textNode) { - // Sometimes happens, since XML values are ambiguous between text and numbers - String textValue = textNode.textValue(); - long value = Long.parseLong(textValue); - result.setValue(value); - } - } else { - result = jsonParser.getCodec().readValue(jsonParser, thisClass); - } - return result; + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + result = construct(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + if (node instanceof NumericNode numNode) { + result.setValue(numNode.longValue()); + } else if (node instanceof TextNode textNode) { + // Sometimes happens, since XML values are ambiguous between text and numbers + String textValue = textNode.textValue(); + long value = Long.parseLong(textValue); + result.setValue(value); + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); } + return result; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java index 3e97059e0..267ffd5f5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfDeserializer.java @@ -1,6 +1,5 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; @@ -11,50 +10,54 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; /** - * Serializer for nested, anonymous SEQUENCE-OF types. Handles XER's way of wrapping these. + * Deserializer for nested, anonymous SEQUENCE-OF types. Handles XER's way of + * wrapping these. + * * @param The Sequence Of type * @author Ivan Yourshaw */ public class NestedSequenceOfDeserializer> extends StdDeserializer { - protected final Class thisClass; - protected final String wrapped; - - protected NestedSequenceOfDeserializer(Class vc, String wrapped) { - super(vc); - this.thisClass = vc; - this.wrapped = wrapped; - } - - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - T result = null; - if (jsonParser instanceof FromXmlParser xmlParser) { - // For XML, we need to remove the wrapper and distinguish between single items and arrays - XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); - TreeNode node = xmlParser.getCodec().readTree(xmlParser); - - if (node instanceof ObjectNode objectNode) { - JsonNode unwrapped = objectNode.findValue(wrapped); - if (unwrapped instanceof ObjectNode unwrappedObject) { - - // Single item not identified as array, so put it in an array - ArrayNode arrayNode = xmlMapper.createArrayNode(); - arrayNode.add(unwrappedObject); - result = xmlMapper.convertValue(arrayNode, thisClass); - - } else if (unwrapped instanceof ArrayNode arrayNode) { - - result = xmlMapper.convertValue(arrayNode, thisClass); - } - } - }else { - result = jsonParser.getCodec().readValue(jsonParser, thisClass); + protected final Class thisClass; + protected final String wrapped; + + protected NestedSequenceOfDeserializer(Class vc, String wrapped) { + super(vc); + this.thisClass = vc; + this.wrapped = wrapped; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + // For XML, we need to remove the wrapper and distinguish between single items + // and arrays + XmlMapper xmlMapper = (XmlMapper) xmlParser.getCodec(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + + if (node instanceof ObjectNode objectNode) { + JsonNode unwrapped = objectNode.findValue(wrapped); + if (unwrapped instanceof ObjectNode unwrappedObject) { + + // Single item not identified as array, so put it in an array + ArrayNode arrayNode = xmlMapper.createArrayNode(); + arrayNode.add(unwrappedObject); + result = xmlMapper.convertValue(arrayNode, thisClass); + + } else if (unwrapped instanceof ArrayNode arrayNode) { + + result = xmlMapper.convertValue(arrayNode, thisClass); } - return result; + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); } + return result; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java index 4ca05d752..154aafc73 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/NestedSequenceOfSerializer.java @@ -1,55 +1,57 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; - -import javax.xml.namespace.QName; import java.io.IOException; +import javax.xml.namespace.QName; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; /** - * Serializer for nested, anonymous SEQUENCT-OF types + * Serializer for nested, anonymous SEQUENCT-OF types. + * * @param The Sequence-of type * @author Ivan Yourshaw */ public class NestedSequenceOfSerializer> extends StdSerializer { - protected final QName wrapped; - - protected NestedSequenceOfSerializer(Class t, String wrapped) { - super(t); - this.wrapped = new QName(wrapped); - } - - @Override - public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - if (serializerProvider instanceof XmlSerializerProvider) { - // Wrapped XER - var xmlGen = (ToXmlGenerator)jsonGenerator; - for (var item : t) { - - xmlGen.writeRaw(String.format("<%s>", wrapped)); - var mapper = SerializationUtil.xmlMapper(); - String itemXml = mapper.writeValueAsString(item); - - // Horrible hack to write the item value without being wrapped by the class name. - // Probably a better way exists, but this works. - String itemClassName = item.getClass().getSimpleName(); - String startElement = String.format("<%s>", itemClassName); - String endElement = String.format("", itemClassName); - String strippedXml = itemXml.replace(startElement, "").replace(endElement, ""); - - xmlGen.writeRaw(strippedXml); - - xmlGen.writeRaw(String.format("", wrapped)); - } - - } else { - // Pass through JER - jsonGenerator.writeObject(t); - } + protected final QName wrapped; + + protected NestedSequenceOfSerializer(Class t, String wrapped) { + super(t); + this.wrapped = new QName(wrapped); + } + + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // Wrapped XER + var xmlGen = (ToXmlGenerator) jsonGenerator; + for (var item : t) { + + xmlGen.writeRaw(String.format("<%s>", wrapped)); + var mapper = SerializationUtil.xmlMapper(); + String itemXml = mapper.writeValueAsString(item); + + // Horrible hack to write the item value without being wrapped by the class + // name. + // Probably a better way exists, but this works. + String itemClassName = item.getClass().getSimpleName(); + String startElement = String.format("<%s>", itemClassName); + String endElement = String.format("", itemClassName); + String strippedXml = itemXml.replace(startElement, "").replace(endElement, ""); + + xmlGen.writeRaw(strippedXml); + + xmlGen.writeRaw(String.format("", wrapped)); + } + + } else { + // Pass through JER + jsonGenerator.writeObject(t); } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java index 28f93a108..dbae0a082 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java @@ -1,6 +1,5 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; @@ -10,45 +9,50 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; - import java.io.IOException; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; /** - * See description in {@link OpenTypeSerializer} + * See description in {@link OpenTypeSerializer}. + * * @author Ivan Yourshaw */ public abstract class OpenTypeDeserializer extends StdDeserializer { - protected final Class thisClass; - protected final String wrapped; - - protected OpenTypeDeserializer(Class vc, String wrapped) { - super(vc); - thisClass = vc; - this.wrapped = wrapped; - } - - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - T result = null; - if (jsonParser instanceof FromXmlParser xmlParser) { - XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); - TreeNode node = xmlParser.getCodec().readTree(xmlParser); - if (node instanceof ObjectNode objectNode) { - JsonNode unwrapped = objectNode.findValue(wrapped); - - // HACK: serialization annotations are ignored here. - // ideally we would like to just unwrap the original literal xml and pass it through - // but Jackson's XML parser insists on converting everything to JSON, so the original XML is - // not preserved. Specifically, empty elements like are expanded to , - // but the boolean and enumerated deserializers can still handle this. - String unwrappedXml = xmlMapper.writeValueAsString(unwrapped); - - result = xmlMapper.readValue(unwrappedXml, thisClass); - } - } else { - result = jsonParser.getCodec().readValue(jsonParser, thisClass); - } - return result; + protected final Class thisClass; + protected final String wrapped; + + protected OpenTypeDeserializer(Class vc, String wrapped) { + super(vc); + thisClass = vc; + this.wrapped = wrapped; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + XmlMapper xmlMapper = (XmlMapper) xmlParser.getCodec(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + if (node instanceof ObjectNode objectNode) { + JsonNode unwrapped = objectNode.findValue(wrapped); + + // HACK: serialization annotations are ignored here. + // ideally we would like to just unwrap the original literal xml and pass it + // through + // but Jackson's XML parser insists on converting everything to JSON, so the + // original XML is + // not preserved. Specifically, empty elements like are expanded to + // , + // but the boolean and enumerated deserializers can still handle this. + String unwrappedXml = xmlMapper.writeValueAsString(unwrapped); + + result = xmlMapper.readValue(unwrappedXml, thisClass); + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); } + return result; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java index 5a2d0bfa6..a672b47fc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeSerializer.java @@ -1,24 +1,25 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.std.StdSerializer; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; - -import javax.xml.namespace.QName; import java.io.IOException; +import javax.xml.namespace.QName; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; /** * Serializer for ASN.1 "open types" which are fields without a specific type, * for dealing with parameterized fields with value sets of different types that - * can be plugged in. In this Java implementation these are represented by type parameters + * can be plugged in. In this Java implementation these are represented by type + * parameters * in abstract types. * *

For example, the contents of the "value" field in a J2735 MessageFrame. * *

XER wraps open types with the type name like: + * *

{@code
  *
  *     
@@ -31,9 +32,11 @@
  *     
  *
  *  }
+ * *

See XMLOpenTypeFieldValue: ITU-T Rec. X.681 (02/2021) Section 14.6. * *

JER does not wrap them: + * *

{@code
  *
  *     {
@@ -44,33 +47,35 @@
  *     }
  *
  * }
+ * *

See "Encoding of open type values", ITU-T Rec X.697 (02/2021), Sec 41. * * @author Ivan Yourshaw */ public abstract class OpenTypeSerializer extends StdSerializer { - protected final QName wrapper; - protected final QName wrapped; + protected final QName wrapper; + protected final QName wrapped; - protected OpenTypeSerializer(Class t, String wrapper, String wrapped) { - super(t); - this.wrapper = new QName(wrapper); - this.wrapped = new QName(wrapped); - } - - @Override - public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { - if (serializerProvider instanceof XmlSerializerProvider) { - // Wrapped XER - var xmlGen = (ToXmlGenerator)jsonGenerator; - xmlGen.startWrappedValue(wrapper, wrapped); - xmlGen.writeObject(t); - xmlGen.finishWrappedValue(wrapper, wrapped); - } else { - // Pass through JER - jsonGenerator.writeObject(t); - } + protected OpenTypeSerializer(Class t, String wrapper, String wrapped) { + super(t); + this.wrapper = new QName(wrapper); + this.wrapped = new QName(wrapped); + } + @Override + public void serialize(T t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (serializerProvider instanceof XmlSerializerProvider) { + // Wrapped XER + var xmlGen = (ToXmlGenerator) jsonGenerator; + xmlGen.startWrappedValue(wrapper, wrapped); + xmlGen.writeObject(t); + xmlGen.finishWrappedValue(wrapper, wrapped); + } else { + // Pass through JER + jsonGenerator.writeObject(t); } + + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java index 72dea516c..fe9a57e63 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/ParameterizedTypeDeserializer.java @@ -1,7 +1,7 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import static us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType.INTEGER; + import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; @@ -9,60 +9,63 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.databind.node.ObjectNode; - import java.io.IOException; - -import static us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType.INTEGER; +import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; /** * Deserialize a parameterized SEQUENCE type. - * Determines the subtype to deserialize to using the {@link Asn1ParameterizedTypes} annotation that + * Determines the subtype to deserialize to using the + * {@link Asn1ParameterizedTypes} annotation that * must be present. * * @param The Sequence Type * * @author Ivan Yourshaw */ -@SuppressWarnings({"unchecked", "rawtypes"}) -public abstract class ParameterizedTypeDeserializer extends StdDeserializer { +@SuppressWarnings({ "unchecked" }) +public abstract class ParameterizedTypeDeserializer + extends StdDeserializer { - protected final Class thisClass; + protected final Class thisClass; - protected ParameterizedTypeDeserializer(Class vc) { - super(vc); - thisClass = vc; - } + protected ParameterizedTypeDeserializer(Class vc) { + super(vc); + thisClass = vc; + } - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - final var typeAnnot = thisClass.getAnnotation(Asn1ParameterizedTypes.class); - if (typeAnnot == null) { - throw new RuntimeException("Missing Asn1ParameterizedTypes annotation."); - } - final String idPropName = typeAnnot.idProperty(); - final Asn1ParameterizedTypes.IdType idType = typeAnnot.idType(); - final Asn1ParameterizedTypes.Type[] types = typeAnnot.value(); - if (types == null || types.length == 0) { - throw new RuntimeException("No Types are defined in the Asn1ParameterizedTypes annotation."); - } - TreeNode node = jsonParser.getCodec().readTree(jsonParser); - if (node instanceof ObjectNode objectNode) { - JsonNode idPropNode = objectNode.findValue(idPropName); - final Object id = (idType == INTEGER) ? idPropNode.asInt() : idPropNode.asText(); - Class subType = getSubtypeForId(id, idType, types); - return (T)jsonParser.getCodec().readValue(jsonParser, subType); - } else { - throw new RuntimeException("Not instance of object"); - } + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + final var typeAnnot = thisClass.getAnnotation(Asn1ParameterizedTypes.class); + if (typeAnnot == null) { + throw new RuntimeException("Missing Asn1ParameterizedTypes annotation."); + } + final String idPropName = typeAnnot.idProperty(); + final Asn1ParameterizedTypes.IdType idType = typeAnnot.idType(); + final Asn1ParameterizedTypes.Type[] types = typeAnnot.value(); + if (types == null || types.length == 0) { + throw new RuntimeException("No Types are defined in the Asn1ParameterizedTypes annotation."); + } + TreeNode node = jsonParser.getCodec().readTree(jsonParser); + if (node instanceof ObjectNode objectNode) { + JsonNode idPropNode = objectNode.findValue(idPropName); + final Object id = (idType == INTEGER) ? idPropNode.asInt() : idPropNode.asText(); + Class subType = getSubtypeForId(id, idType, types); + return (T) jsonParser.getCodec().readValue(jsonParser, subType); + } else { + throw new RuntimeException("Not instance of object"); } + } - private Class getSubtypeForId(final Object id, Asn1ParameterizedTypes.IdType idType, Asn1ParameterizedTypes.Type[] types) { - for (var theType : types) { - Object idValue = (idType == INTEGER) ? theType.intId() : theType.stringId(); - if (id.equals(idValue)) { - return theType.value(); - } - } - throw new RuntimeException(String.format("Id %s not found in list of types", id)); + private Class getSubtypeForId(final Object id, Asn1ParameterizedTypes.IdType idType, + Asn1ParameterizedTypes.Type[] types) { + for (var theType : types) { + Object idValue = (idType == INTEGER) ? theType.intId() : theType.stringId(); + if (id.equals(idValue)) { + return theType.value(); + } } + throw new RuntimeException(String.format("Id %s not found in list of types", id)); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java index 6b69eb5f8..c798fc5e8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfEnumeratedDeserializer.java @@ -1,52 +1,60 @@ package us.dot.its.jpo.ode.plugin.serialization; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.TreeNode; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; - import java.io.IOException; import java.util.Objects; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -public abstract class SequenceOfEnumeratedDeserializer & Asn1Enumerated, T extends Asn1SequenceOf> - extends StdDeserializer { - - protected final Class thisClass; - protected final Class enumClass; - protected abstract S[] listEnumValues(); - protected abstract T construct(); - - protected SequenceOfEnumeratedDeserializer(Class sequenceOfEnumType, Class enumType) { - super(sequenceOfEnumType); - this.thisClass = sequenceOfEnumType; - this.enumClass = enumType; - } - - @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { - T result = null; - if (jsonParser instanceof FromXmlParser xmlParser) { - // Unwrapped enum items - result = construct(); - TreeNode node = xmlParser.getCodec().readTree(xmlParser); - - var fieldNameIterator = node.fieldNames(); - while (fieldNameIterator.hasNext()) { - String name = fieldNameIterator.next(); - - for (S enumValue : listEnumValues()) { - if (Objects.equals(enumValue.getName(), name)) { - result.add(enumValue); - } - } - } - } else { - result = jsonParser.getCodec().readValue(jsonParser, thisClass); +/** + * Base class for deserializers for SEQUENCE-OF ENUMERATED types. + * + * @param The Sequence Of ENUMERATED type. + * @author Ivan Yourshaw + */ +public abstract class SequenceOfEnumeratedDeserializer & Asn1Enumerated, + T extends Asn1SequenceOf> extends StdDeserializer { + + protected final Class thisClass; + protected final Class enumClass; + + protected abstract S[] listEnumValues(); + + protected abstract T construct(); + + protected SequenceOfEnumeratedDeserializer(Class sequenceOfEnumType, Class enumType) { + super(sequenceOfEnumType); + this.thisClass = sequenceOfEnumType; + this.enumClass = enumType; + } + + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T result = null; + if (jsonParser instanceof FromXmlParser xmlParser) { + // Unwrapped enum items + result = construct(); + TreeNode node = xmlParser.getCodec().readTree(xmlParser); + + var fieldNameIterator = node.fieldNames(); + while (fieldNameIterator.hasNext()) { + String name = fieldNameIterator.next(); + + for (S enumValue : listEnumValues()) { + if (Objects.equals(enumValue.getName(), name)) { + result.add(enumValue); + } } - return result; + } + } else { + result = jsonParser.getCodec().readValue(jsonParser, thisClass); } + return result; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java index 8b7cb9f5a..bad8dd867 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SerializationUtil.java @@ -3,16 +3,21 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper; +/** + * Utility class to perform serialization and deserialization with static JSON and XML mappers. + * + * @author Ivan Yourshaw + */ public class SerializationUtil { - private static final ObjectMapper jsonMapper = new ObjectMapper(); - private static final XmlMapper xmlMapper = new XmlMapper(); + private static final ObjectMapper jsonMapper = new ObjectMapper(); + private static final XmlMapper xmlMapper = new XmlMapper(); - public static ObjectMapper jsonMapper() { - return jsonMapper; - } + public static ObjectMapper jsonMapper() { + return jsonMapper; + } - public static XmlMapper xmlMapper() { - return xmlMapper; - } + public static XmlMapper xmlMapper() { + return xmlMapper; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java index eb0cce231..e14381551 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Bitstring.java @@ -1,135 +1,167 @@ package us.dot.its.jpo.ode.plugin.types; -import com.fasterxml.jackson.annotation.JsonIgnore; -import us.dot.its.jpo.ode.plugin.serialization.BitstringSerializer; +import static us.dot.its.jpo.ode.plugin.utils.BitUtils.reverseBits; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import java.util.BitSet; import java.util.HexFormat; -import java.util.LinkedHashMap; -import java.util.Map; - -import static us.dot.its.jpo.ode.plugin.utils.BitUtils.reverseBits; +import us.dot.its.jpo.ode.plugin.serialization.BitstringSerializer; +/** + * Base class for an ASN.1 bitstring. + */ @JsonSerialize(using = BitstringSerializer.class) public abstract class Asn1Bitstring implements Asn1Type { - @JsonIgnore - final BitSet bits; - - @JsonIgnore - final int size; - - @JsonIgnore - final boolean hasExtensionMarker; - - @JsonIgnore - final String[] names; - - public Asn1Bitstring(int size, boolean hasExtensionMarker, String[] names) { - this.size = size; - this.hasExtensionMarker = hasExtensionMarker; - this.bits = new BitSet(size); - this.names = names; - } - - public int size() { - return size; - } - - public boolean hasExtensionMarker() { - return hasExtensionMarker; - } - - public boolean get(int bitIndex) { - return bits.get(bitIndex); + @JsonIgnore + final BitSet bits; + + @JsonIgnore + final int size; + + @JsonIgnore + final boolean hasExtensionMarker; + + @JsonIgnore + final String[] names; + + /** + * Creates a Asn1Bitstring with the specified number of items and name values. + * + * @param size The length of the bitstring. + * @param hasExtensionMarker Presence of any ASN.1 bitstring extension values. + * @param names The String name values corresponding to each bit in the bitstring. + */ + public Asn1Bitstring(int size, boolean hasExtensionMarker, String[] names) { + this.size = size; + this.hasExtensionMarker = hasExtensionMarker; + this.bits = new BitSet(size); + this.names = names; + } + + public int size() { + return size; + } + + public boolean hasExtensionMarker() { + return hasExtensionMarker; + } + + public boolean get(int bitIndex) { + return bits.get(bitIndex); + } + + public void set(int bitIndex, boolean value) { + bits.set(bitIndex, value); + } + + /** + * Set the corresponding bit from the bitstring based on the name value. + * + * @param name The name String value for the corresponding bit in the bitstring. + * @param value The value for the bit to be set. + */ + public void set(String name, boolean value) { + for (int i = 0; i < size; i++) { + if (name(i).equals(name)) { + set(i, value); + return; + } } - - public void set(int bitIndex, boolean value) { - bits.set(bitIndex, value); + throw new IllegalArgumentException("Unknown name " + name); + } + + /** + * Gets the String value of the bitstring represented in binary. + */ + public String binaryString() { + char[] chars = new char[size]; + for (int i = 0; i < size; i++) { + chars[i] = get(i) ? '1' : '0'; } - - public void set(String name, boolean value) { - for (int i = 0; i < size; i++) { - if (name(i).equals(name)) { - set(i, value); - return; - } - } - throw new IllegalArgumentException("Unknown name " + name); - } - - public String binaryString() { - char[] chars = new char[size]; - for (int i = 0; i < size; i++) { - chars[i] = get(i) ? '1' : '0'; - } - return new String(chars); + return new String(chars); + } + + public String hexString() { + HexFormat hex = HexFormat.of(); + return hex.formatHex(reverseBits(bits.toByteArray())); + } + + /** + * Sets the Asn1Bitstring values from a String binary representation of a bitstring. + * + * @param str The bitstring represented in binary. + */ + public void fromBinaryString(String str) { + if (str == null) { + bits.clear(); + return; } - - public String hexString() { - HexFormat hex = HexFormat.of(); - return hex.formatHex(reverseBits(bits.toByteArray())); + char[] chars = str.toCharArray(); + if (chars.length < size) { + throw new IllegalArgumentException("Not enough characters in string " + str); } - - public void fromBinaryString(String str) { - if (str == null) { - bits.clear(); - return; - } - char[] chars = str.toCharArray(); - if (chars.length < size) { - throw new IllegalArgumentException("Not enough characters in string " + str); - } - for (int i = 0; i < size; i++) { - char c = chars[i]; - set(i, c == '1'); - } + for (int i = 0; i < size; i++) { + char c = chars[i]; + set(i, c == '1'); } - - public void fromHexString(String str) { - System.out.println(str); - if (str == null) { - bits.clear(); - return; - } - HexFormat hex = HexFormat.of(); - byte[] bytes = reverseBits(hex.parseHex(str)); - System.out.println(bytes.length); - BitSet newBits = BitSet.valueOf(bytes); - System.out.println(newBits); - - bits.clear(); - bits.or(newBits); - System.out.println(binaryString()); + } + + /** + * Sets the Asn1Bitstring values from a String hex representation of a bitstring. + * + * @param str The bitstring represented in hex. + */ + public void fromHexString(String str) { + System.out.println(str); + if (str == null) { + bits.clear(); + return; } - - public String name(int index) { - if (index < 0 || index >= size()) { - throw new IllegalArgumentException(String.format("Index %s out of range %s-%s", index, 0, size())); - } - return names[index]; + HexFormat hex = HexFormat.of(); + byte[] bytes = reverseBits(hex.parseHex(str)); + System.out.println(bytes.length); + BitSet newBits = BitSet.valueOf(bytes); + System.out.println(newBits); + + bits.clear(); + bits.or(newBits); + System.out.println(binaryString()); + } + + /** + * Get the name representing the requested index. + * + * @param index The index value of the bitstring being requested. + */ + public String name(int index) { + if (index < 0 || index >= size()) { + throw new IllegalArgumentException( + String.format("Index %s out of range %s-%s", index, 0, size())); } - - @Override - public int hashCode() { - return bits.hashCode(); + return names[index]; + } + + @Override + public int hashCode() { + return bits.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; } - - @Override - public boolean equals(Object obj) { - if (obj == null) return false; - if (obj instanceof Asn1Bitstring bitstring) { - return bits.equals(bitstring.bits); - } else { - return false; - } + if (obj instanceof Asn1Bitstring bitstring) { + return bits.equals(bitstring.bits); + } else { + return false; } + } - @Override - public String toString() { - return binaryString(); - } + @Override + public String toString() { + return binaryString(); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java index f20dd969a..371845a5c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Boolean.java @@ -1,55 +1,59 @@ package us.dot.its.jpo.ode.plugin.types; -import us.dot.its.jpo.ode.plugin.serialization.BooleanDeserializer; -import us.dot.its.jpo.ode.plugin.serialization.BooleanSerializer; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; - import java.util.Objects; +import us.dot.its.jpo.ode.plugin.serialization.BooleanDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.BooleanSerializer; - - +/** + * Class representing an ASN.1 boolean. + */ @JsonSerialize(using = BooleanSerializer.class) @JsonDeserialize(using = BooleanDeserializer.class) public class Asn1Boolean implements Asn1Type { - public Asn1Boolean() {} + public Asn1Boolean() { + } - @JsonCreator - public Asn1Boolean(boolean value) { - this.value = value; - } + @JsonCreator + public Asn1Boolean(boolean value) { + this.value = value; + } - private boolean value; + private boolean value; - @JsonValue - public boolean getValue() { - return value; - } + @JsonValue + public boolean getValue() { + return value; + } - public void setValue(boolean value) { - this.value = value; - } + public void setValue(boolean value) { + this.value = value; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Asn1Boolean that = (Asn1Boolean) o; - return value == that.value; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public int hashCode() { - return Objects.hashCode(value); + if (o == null || getClass() != o.getClass()) { + return false; } - - @Override - public String toString() { - return Boolean.toString(value); - } - + Asn1Boolean that = (Asn1Boolean) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @Override + public String toString() { + return Boolean.toString(value); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java index 095a00cc8..7249096ac 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1CharacterString.java @@ -2,40 +2,49 @@ import com.fasterxml.jackson.annotation.JsonValue; -//@JsonSerialize(using = CharacterStringSerializer.class) +/** + * Base class for an ASN.1 character string. + */ public abstract class Asn1CharacterString implements Asn1Type { - protected final int minLength; - protected final int maxLength; - protected String value; - - public Asn1CharacterString(int minLength, int maxLength) { - this.minLength = minLength; - this.maxLength = maxLength; - } - - @JsonValue - public String getValue() { - return value; + protected final int minLength; + protected final int maxLength; + protected String value; + + public Asn1CharacterString(int minLength, int maxLength) { + this.minLength = minLength; + this.maxLength = maxLength; + } + + @JsonValue + public String getValue() { + return value; + } + + /** + * Sets the character string to value. + * + * @param value The String value that the Asn1CharacterString will be set to. + */ + public void setValue(String value) { + if (!validate(value)) { + throw new IllegalArgumentException( + String.format("String '%s' has invalid length. Must be between %d and %s", + value, minLength, maxLength)); } + this.value = value; + } - public void setValue(String value) { - if (!validate(value)) { - throw new IllegalArgumentException( - String.format("String '%s' has invalid length. Must be between %d and %s", - value, minLength, maxLength)); - } - this.value = value; + protected boolean validate(String valueA) { + if (valueA == null) { + return true; } + return valueA.length() >= minLength && valueA.length() <= maxLength; + } - protected boolean validate(String aValue) { - if (aValue == null) return true; - return aValue.length() >= minLength && aValue.length() <= maxLength; - } - - @Override - public String toString() { - return value; - } + @Override + public String toString() { + return value; + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java index f6805baaa..a9fab258d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java @@ -1,62 +1,62 @@ package us.dot.its.jpo.ode.plugin.types; -import com.fasterxml.jackson.annotation.JsonIgnore; -import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; - import java.util.List; import java.util.Optional; +import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; +/** + * Base class for an ASN.1 choice. + */ public abstract class Asn1Choice implements Asn1Type { - @JsonIgnore - final boolean hasExtensionMarker; - - public Asn1Choice(boolean hasExtensionMarker) { - this.hasExtensionMarker = hasExtensionMarker; - } - - /** - * Validates if one and only one option is selected for the choice - */ - protected boolean isValid() { - var types = listTypes(); - long numChosen = types.stream().filter(Optional::isPresent).count(); - return numChosen == 1; + @JsonIgnore + final boolean hasExtensionMarker; + + public Asn1Choice(boolean hasExtensionMarker) { + this.hasExtensionMarker = hasExtensionMarker; + } + + /** + * Validates if one and only one option is selected for the choice. + */ + protected boolean isValid() { + var types = listTypes(); + long numChosen = types.stream().filter(Optional::isPresent).count(); + return numChosen == 1; + } + + /** + * Ref ITU-T X.691 (02/2021) Section 23. + * + * @return the index of the chosen alternative + */ + protected int chosenIndex() { + List> types = listTypes(); + for (int i = 0; i < types.size(); i++) { + if (types.get(i).isPresent()) { + return i; + } } - - /** - * Ref ITU-T X.691 (02/2021) Section 23 - * @return the index of the chosen alternative - */ - protected int chosenIndex() { - List> types = listTypes(); - for (int i = 0; i < types.size(); i++) { - if (types.get(i).isPresent()) return i; - } - return -1; - } - - protected int maxIndex() { - return listTypes().size() - 1; - } - - abstract protected List> listTypes(); - - - - - @Override - public String toString() { - ObjectMapper mapper = SerializationUtil.jsonMapper(); - try { - return mapper.writeValueAsString(this); - } catch (JsonProcessingException e) { - System.err.println(e.getMessage()); - return ""; - } + return -1; + } + + protected int maxIndex() { + return listTypes().size() - 1; + } + + protected abstract List> listTypes(); + + @Override + public String toString() { + ObjectMapper mapper = SerializationUtil.jsonMapper(); + try { + return mapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + System.err.println(e.getMessage()); + return ""; } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java index 6257707b3..0728eecb6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Enumerated.java @@ -1,10 +1,15 @@ package us.dot.its.jpo.ode.plugin.types; +/** + * Class for an ASN.1 enumerated object. + */ public interface Asn1Enumerated extends Asn1Type { - int getIndex(); - String getName(); - boolean hasExtensionMarker(); - int maxIndex(); + int getIndex(); + String getName(); + + boolean hasExtensionMarker(); + + int maxIndex(); } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java index c3ef31ccb..b27348b93 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Integer.java @@ -2,72 +2,76 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonValue; - import java.util.Objects; /** * A constrained integer type with lower bound and upper bound. - * Unconstrained integer types and extensibility markers in integer constraints are not supported. + * Unconstrained integer types and extensibility markers in integer constraints + * are not supported. */ -//@JsonSerialize(using = IntegerSerializer.class) public class Asn1Integer implements Asn1Type, Comparable { - protected long value; + protected long value; - @JsonIgnore - final long lowerBound; + @JsonIgnore + final long lowerBound; - @JsonIgnore - final long upperBound; + @JsonIgnore + final long upperBound; - public Asn1Integer(long lowerBound, long upperBound) { - this.lowerBound = lowerBound; - this.upperBound = upperBound; - } + public Asn1Integer(long lowerBound, long upperBound) { + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } - @JsonValue - public long getValue() { - return value; - } + @JsonValue + public long getValue() { + return value; + } - public void setValue(long value) { - this.value = value; - } + public void setValue(long value) { + this.value = value; + } - public int intValue() { - return (int)value; - } + public int intValue() { + return (int) value; + } - @Override - public int compareTo(Asn1Integer other) { - if (other == null) return -1; - return Long.compare(value, other.value); + @Override + public int compareTo(Asn1Integer other) { + if (other == null) { + return -1; } + return Long.compare(value, other.value); + } - public long getLowerBound() { - return lowerBound; - } - - public long getUpperBound() { - return upperBound; - } + public long getLowerBound() { + return lowerBound; + } + public long getUpperBound() { + return upperBound; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Asn1Integer that = (Asn1Integer) o; - return value == that.value; + @Override + public boolean equals(Object o) { + if (this == o) { + return true; } - - @Override - public int hashCode() { - return Objects.hashCode(value); - } - - @Override - public String toString() { - return Long.toString(value); + if (o == null || getClass() != o.getClass()) { + return false; } + Asn1Integer that = (Asn1Integer) o; + return value == that.value; + } + + @Override + public int hashCode() { + return Objects.hashCode(value); + } + + @Override + public String toString() { + return Long.toString(value); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java index 14081d391..927eff5af 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java @@ -1,11 +1,12 @@ package us.dot.its.jpo.ode.plugin.types; +/** + * Class for an ASN.1 octet string. + */ public class Asn1OctetString extends Asn1CharacterString { - public Asn1OctetString(int minLength, int maxLength) { - super(minLength, maxLength); - } - - + public Asn1OctetString(int minLength, int maxLength) { + super(minLength, maxLength); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java index 0f0d49a50..ce18cfcfa 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Sequence.java @@ -1,36 +1,35 @@ package us.dot.its.jpo.ode.plugin.types; -import com.fasterxml.jackson.annotation.JsonIgnore; -import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; +/** + * Base class for an ASN.1 sequence. + */ public abstract class Asn1Sequence implements Asn1Type { - @JsonIgnore - final boolean extensionMarker; - - public Asn1Sequence(boolean hasExtensionMarker) { - this.extensionMarker = hasExtensionMarker; - } - - @JsonIgnore - public boolean hasExtensionMarker() { - return extensionMarker; - } - - - - @Override - public String toString() { - ObjectMapper mapper = SerializationUtil.jsonMapper(); - try { - return mapper.writeValueAsString(this); - } catch (JsonProcessingException e) { - System.err.println(e.getMessage()); - return ""; - } + @JsonIgnore + final boolean extensionMarker; + + public Asn1Sequence(boolean hasExtensionMarker) { + this.extensionMarker = hasExtensionMarker; + } + + @JsonIgnore + public boolean hasExtensionMarker() { + return extensionMarker; + } + + @Override + public String toString() { + ObjectMapper mapper = SerializationUtil.jsonMapper(); + try { + return mapper.writeValueAsString(this); + } catch (JsonProcessingException e) { + System.err.println(e.getMessage()); + return ""; } + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java index 703fa802f..96d6f1d13 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1SequenceOf.java @@ -1,41 +1,50 @@ package us.dot.its.jpo.ode.plugin.types; import com.fasterxml.jackson.annotation.JsonIgnore; - import java.util.ArrayList; - +/** + * Base class for an ASN.1 sequence-of. + */ public abstract class Asn1SequenceOf extends ArrayList implements Asn1Type { - final Class itemClass; - final long sizeLowerBound; - final long sizeUpperBound; - - public Asn1SequenceOf(Class itemClass, long sizeLowerBound, long sizeUpperBound) { - this.itemClass = itemClass; - this.sizeLowerBound = sizeLowerBound; - this.sizeUpperBound = sizeUpperBound; - } - - @JsonIgnore - public Class getItemClass() { - return itemClass; - } - - @JsonIgnore - public long getSizeLowerBound() { - return sizeLowerBound; - } - - @JsonIgnore - public long getSizeUpperBound() { - return sizeUpperBound; - } - - @SuppressWarnings("unchecked") - public boolean add(Asn1Type item) { - return super.add((T)item); - } + final Class itemClass; + final long sizeLowerBound; + final long sizeUpperBound; + + /** + * Creates a Asn1SequenceOf with the specified generic object type along with + * an upper and lower number of items in the sequence-of array. + * + * @param itemClass The type of object the SequenceOf consists of. + * @param sizeLowerBound The lowest allowed number of items inside the Asn1SequenceOf array. + * @param sizeUpperBound The highest allowed number of items inside the Asn1SequenceOf array. + */ + public Asn1SequenceOf(Class itemClass, long sizeLowerBound, long sizeUpperBound) { + this.itemClass = itemClass; + this.sizeLowerBound = sizeLowerBound; + this.sizeUpperBound = sizeUpperBound; + } + + @JsonIgnore + public Class getItemClass() { + return itemClass; + } + + @JsonIgnore + public long getSizeLowerBound() { + return sizeLowerBound; + } + + @JsonIgnore + public long getSizeUpperBound() { + return sizeUpperBound; + } + + @SuppressWarnings("unchecked") + public boolean add(Asn1Type item) { + return super.add((T) item); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java index 54a4d3834..11f549558 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/IA5String.java @@ -6,10 +6,8 @@ */ public class IA5String extends Asn1CharacterString { - - public IA5String(int minLength, int maxLength) { - super(minLength, maxLength); - } - + public IA5String(int minLength, int maxLength) { + super(minLength, maxLength); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java index 101408f14..3152fc04c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/UnknownType.java @@ -3,6 +3,7 @@ /** * Placeholder for unknown types in the generated source. * If classes of this type exist, it means the ASN.1 specification has an unsupported feature. + * * @author Ivan Yourshaw */ public class UnknownType implements Asn1Type { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index 3e9c440fa..08cc320a5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -1,12 +1,10 @@ package us.dot.its.jpo.ode.coder; -import java.io.IOException; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; - +import java.io.IOException; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimData; @@ -19,48 +17,69 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +/** + * Helper class for deserializing TIM messages in XML/XER format into POJOs. + */ public class OdeTimDataCreatorHelper { - public static OdeTimData createOdeTimDataFromDecoded(String consumedData) throws XmlUtilsException { - ObjectNode consumed = XmlUtils.toObjectNode(consumedData); + /** + * Deserializes XML/XER from the UDP decoded pipeline. + * + * @param consumedData The XML/XER as a String. + */ + public static OdeTimData createOdeTimDataFromDecoded(String consumedData) + throws XmlUtilsException { + ObjectNode consumed = XmlUtils.toObjectNode(consumedData); - JsonNode metadataNode = consumed.findValue(AppContext.METADATA_STRING); - if (metadataNode instanceof ObjectNode) { - ObjectNode object = (ObjectNode) metadataNode; - object.remove(AppContext.ENCODINGS_STRING); + JsonNode metadataNode = consumed.findValue(AppContext.METADATA_STRING); + if (metadataNode instanceof ObjectNode) { + ObjectNode object = (ObjectNode) metadataNode; + object.remove(AppContext.ENCODINGS_STRING); - // Map header file does not have a location and use predefined set required - // RxSource - ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); - receivedMessageDetails.setRxSource(RxSource.NA); - ObjectMapper objectMapper = new ObjectMapper(); - JsonNode jsonNode; - try { - jsonNode = objectMapper.readTree(receivedMessageDetails.toJson()); - object.set(AppContext.RECEIVEDMSGDETAILS_STRING, jsonNode); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } + // Map header file does not have a location and use predefined set required + // RxSource + ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); + receivedMessageDetails.setRxSource(RxSource.NA); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode jsonNode; + try { + jsonNode = objectMapper.readTree(receivedMessageDetails.toJson()); + object.set(AppContext.RECEIVEDMSGDETAILS_STRING, jsonNode); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } - OdeTimMetadata metadata = (OdeTimMetadata) JsonUtils.fromJson(metadataNode.toString(), OdeTimMetadata.class); + OdeTimMetadata metadata = (OdeTimMetadata) JsonUtils.fromJson(metadataNode.toString(), + OdeTimMetadata.class); - if (metadata.getSchemaVersion() <= 4) { - metadata.setReceivedMessageDetails(null); - } + if (metadata.getSchemaVersion() <= 4) { + metadata.setReceivedMessageDetails(null); + } - String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, "TravelerInformation"); - TravelerInformation timObject = (TravelerInformation)XmlUtils.fromXmlS(travelerInformationXml, TravelerInformation.class); - OdeTimPayload payload = new OdeTimPayload(timObject); - return new OdeTimData(metadata, payload); - } + String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, + "TravelerInformation"); + TravelerInformation timObject = (TravelerInformation) XmlUtils.fromXmlS(travelerInformationXml, + TravelerInformation.class); + OdeTimPayload payload = new OdeTimPayload(timObject); + return new OdeTimData(metadata, payload); + } - public static OdeTimData createOdeTimDataFromCreator(String consumedData, OdeMsgMetadata metadata) throws XmlUtilsException { - String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, "TravelerInformation"); - TravelerInformation timObject = (TravelerInformation)XmlUtils.fromXmlS(travelerInformationXml, TravelerInformation.class); - OdeTimPayload payload = new OdeTimPayload(timObject); - return new OdeTimData(metadata, payload); - } + /** + * Deserializes XML/XER from the TIM creator endpoint. + * + * @param consumedData The XML/XER as a String. + * @param metadata The pre-built ODE metadata object with unique TIM creator data. + */ + public static OdeTimData createOdeTimDataFromCreator(String consumedData, OdeMsgMetadata metadata) + throws XmlUtilsException { + String travelerInformationXml = XmlUtils.findXmlContentString(consumedData, + "TravelerInformation"); + TravelerInformation timObject = (TravelerInformation) XmlUtils.fromXmlS(travelerInformationXml, + TravelerInformation.class); + OdeTimPayload payload = new OdeTimPayload(timObject); + return new OdeTimData(metadata, payload); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index b2726e389..76071de23 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -1,34 +1,49 @@ /******************************************************************************* * Copyright 2018 572682 * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.traveler; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.format.DateTimeParseException; +import java.util.Date; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata.GeneratedBy; -import us.dot.its.jpo.ode.model.*; +import us.dot.its.jpo.ode.model.OdeMsgPayload; +import us.dot.its.jpo.ode.model.OdeObject; +import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; +import us.dot.its.jpo.ode.model.OdeTimData; +import us.dot.its.jpo.ode.model.OdeTravelerInputData; +import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.ServiceRequest; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal; import us.dot.its.jpo.ode.plugin.ServiceRequest.OdeInternal.RequestVerb; @@ -45,269 +60,289 @@ import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeTimSerializer; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.format.DateTimeParseException; -import java.util.Date; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - +/** + * The REST controller for handling TIM creation requests. + */ @RestController @Slf4j public class TimDepositController { - private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); + private static final TimIngestTracker INGEST_MONITOR = TimIngestTracker.getInstance(); - private static final String ERRSTR = "error"; - private static final String WARNING = "warning"; - private static final String SUCCESS = "success"; + private static final String ERRSTR = "error"; + private static final String WARNING = "warning"; + private static final String SUCCESS = "success"; - private final Asn1CoderTopics asn1CoderTopics; - private final PojoTopics pojoTopics; - private final JsonTopics jsonTopics; + private final Asn1CoderTopics asn1CoderTopics; + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; - private final SerialId serialIdJ2735; - private final SerialId serialIdOde; + private final SerialId serialIdJ2735; + private final SerialId serialIdOde; - private final MessageProducer stringMsgProducer; - private final MessageProducer timProducer; + private final MessageProducer stringMsgProducer; + private final MessageProducer timProducer; - private final boolean dataSigningEnabledSDW; + private final boolean dataSigningEnabledSDW; - public static class TimDepositControllerException extends Exception { + /** + * Unique exception for the TimDepositController to handle error state responses to the client. + */ + public static class TimDepositControllerException extends Exception { - private static final long serialVersionUID = 1L; - - public TimDepositControllerException(String errMsg) { - super(errMsg); - } + private static final long serialVersionUID = 1L; + public TimDepositControllerException(String errMsg) { + super(errMsg); } - @Autowired - public TimDepositController(OdeKafkaProperties odeKafkaProperties, - Asn1CoderTopics asn1CoderTopics, - PojoTopics pojoTopics, - JsonTopics jsonTopics, - TimIngestTrackerProperties ingestTrackerProperties, - SecurityServicesProperties securityServicesProperties) { - super(); - - this.asn1CoderTopics = asn1CoderTopics; - this.pojoTopics = pojoTopics; - this.jsonTopics = jsonTopics; - this.serialIdJ2735 = new SerialId(); - this.serialIdOde = new SerialId(); - - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), - null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); - - this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); - - // start the TIM ingest monitoring service if enabled - if (ingestTrackerProperties.isTrackingEnabled()) { - log.info("TIM ingest monitoring enabled."); - - ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); - - scheduledExecutorService.scheduleAtFixedRate( - new TimIngestWatcher(ingestTrackerProperties.getInterval()), - ingestTrackerProperties.getInterval(), - ingestTrackerProperties.getInterval(), - java.util.concurrent.TimeUnit.SECONDS); - } else { - log.info("TIM ingest monitoring disabled."); - } + } + + /** + * Spring Autowired constructor for the REST controller to properly initialize. + */ + @Autowired + public TimDepositController(OdeKafkaProperties odeKafkaProperties, + Asn1CoderTopics asn1CoderTopics, + PojoTopics pojoTopics, + JsonTopics jsonTopics, + TimIngestTrackerProperties ingestTrackerProperties, + SecurityServicesProperties securityServicesProperties) { + super(); + + this.asn1CoderTopics = asn1CoderTopics; + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + this.serialIdJ2735 = new SerialId(); + this.serialIdOde = new SerialId(); + + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), null, + OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); + + this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); + + // start the TIM ingest monitoring service if enabled + if (ingestTrackerProperties.isTrackingEnabled()) { + log.info("TIM ingest monitoring enabled."); + + ScheduledExecutorService scheduledExecutorService = Executors + .newSingleThreadScheduledExecutor(); + + scheduledExecutorService.scheduleAtFixedRate( + new TimIngestWatcher(ingestTrackerProperties.getInterval()), + ingestTrackerProperties.getInterval(), + ingestTrackerProperties.getInterval(), + java.util.concurrent.TimeUnit.SECONDS); + } else { + log.info("TIM ingest monitoring disabled."); + } + } + + /** + * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST + * + * @param jsonString The value of the JSON message + * @param verb The HTTP verb being requested + * @return The request completion status + */ + public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { + + if (null == jsonString || jsonString.isEmpty()) { + String errMsg = "Empty request."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - /** - * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST - * - * @param jsonString - * @param verb - * @return - */ - public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { - - if (null == jsonString || jsonString.isEmpty()) { - String errMsg = "Empty request."; - log.error(errMsg); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - OdeTravelerInputData odeTID; - ServiceRequest request; - try { - // Convert JSON to POJO - odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, OdeTravelerInputData.class, true); - if (odeTID == null) { - String errMsg = "Malformed or non-compliant JSON syntax."; - log.error(errMsg); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - request = odeTID.getRequest(); - if (request == null) { - throw new TimDepositControllerException("Request element is required as of version 3."); - } - - if (request.getOde() == null) { - request.setOde(new OdeInternal()); - } - - request.getOde().setVerb(verb); - - } catch (TimDepositControllerException e) { - String errMsg = "Missing or invalid argument: " + e.getMessage(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } catch (JsonUtilsException e) { - String errMsg = "Malformed or non-compliant JSON syntax."; - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } - - // Add metadata to message and publish to kafka - OdeTravelerInformationMessage tim = odeTID.getTim(); - OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); - OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); - - // set packetID in tim Metadata - timMetadata.setOdePacketID(tim.getPacketID()); - // set maxDurationTime in tim Metadata and set latest startDatetime in tim - // metadata - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - if (null != tim.getDataframes() && tim.getDataframes().length > 0) { - int maxDurationTime = 0; - Date latestStartDateTime = null; - for (DataFrame dataFrameItem : tim.getDataframes()) { - maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); - try { - latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null - && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime); - } catch (ParseException e) { - log.error("Invalid dateTime parse: ", e); - } - } - timMetadata.setMaxDurationTime(maxDurationTime); - timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); - } - // Setting the SerialId to OdeBradcastTim serialId to be changed to - // J2735BroadcastTim serialId after the message has been published to - // OdeTimBrodcast topic - timMetadata.setSerialId(serialIdOde); - timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); + OdeTravelerInputData odeTID; + ServiceRequest request; + try { + // Convert JSON to POJO + odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, + OdeTravelerInputData.class, true); + if (odeTID == null) { + String errMsg = "Malformed or non-compliant JSON syntax."; + log.error(errMsg); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + + request = odeTID.getRequest(); + if (request == null) { + throw new TimDepositControllerException("Request element is required as of version 3."); + } + + if (request.getOde() == null) { + request.setOde(new OdeInternal()); + } + + request.getOde().setVerb(verb); + + } catch (TimDepositControllerException e) { + String errMsg = "Missing or invalid argument: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } catch (JsonUtilsException e) { + String errMsg = "Malformed or non-compliant JSON syntax."; + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } + // Add metadata to message and publish to kafka + OdeTravelerInformationMessage tim = odeTID.getTim(); + OdeMsgPayload timDataPayload = new OdeMsgPayload(tim); + OdeRequestMsgMetadata timMetadata = new OdeRequestMsgMetadata(timDataPayload, request); + + // set packetID in tim Metadata + timMetadata.setOdePacketID(tim.getPacketID()); + // set maxDurationTime in tim Metadata and set latest startDatetime in tim + // metadata + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + if (null != tim.getDataframes() && tim.getDataframes().length > 0) { + int maxDurationTime = 0; + Date latestStartDateTime = null; + for (DataFrame dataFrameItem : tim.getDataframes()) { + maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); try { - timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime(DateTimeUtils.isoDateTime(tim.getTimeStamp()))); - } catch (DateTimeParseException e) { - String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + latestStartDateTime = (latestStartDateTime == null || (latestStartDateTime != null + && latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime()))) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) + : latestStartDateTime); + } catch (ParseException e) { + log.error("Invalid dateTime parse: ", e); } + } + timMetadata.setMaxDurationTime(maxDurationTime); + timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); + } + // Setting the SerialId to OdeBradcastTim serialId to be changed to + // J2735BroadcastTim serialId after the message has been published to + // OdeTimBrodcast topic + timMetadata.setSerialId(serialIdOde); + timMetadata.setRecordGeneratedBy(GeneratedBy.TMC); + + try { + timMetadata.setRecordGeneratedAt(DateTimeUtils.isoDateTime( + DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + } catch (DateTimeParseException e) { + String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + } - OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); - timProducer.send(pojoTopics.getTimBroadcast(), null, odeTimData); - - String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); - stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); - - // Now that the message has been published to OdeBroadcastTim topic, it should - // be - // changed to J2735BroadcastTim serialId - timMetadata.setSerialId(serialIdJ2735); + OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); + timProducer.send(pojoTopics.getTimBroadcast(), null, odeTimData); - // Short circuit - // If the TIM has no RSU/SNMP or SDW structures, we are done - if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { - String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams."; - log.warn(warningMsg); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); - } + String obfuscatedTimData = TimTransmogrifier.obfuscateRsuPassword(odeTimData.toJson()); + stringMsgProducer.send(jsonTopics.getTimBroadcast(), null, obfuscatedTimData); - // Craft ASN-encodable TIM - ObjectNode encodableTid; - try { - encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); - TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); + // Now that the message has been published to OdeBroadcastTim topic, it should + // be + // changed to J2735BroadcastTim serialId + timMetadata.setSerialId(serialIdJ2735); - log.debug("Encodable Traveler Information Data: {}", encodableTid); + // Short circuit + // If the TIM has no RSU/SNMP or SDW structures, we are done + if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { + String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields. " + + "Message only published to broadcast streams."; + log.warn(warningMsg); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); + } - } catch (JsonUtilsException e) { - String errMsg = "Error converting to encodable TravelerInputData."; - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } + // Craft ASN-encodable TIM + ObjectNode encodableTid; + try { + encodableTid = JsonUtils.toObjectNode(odeTID.toJson()); + TravelerMessageFromHumanToAsnConverter.convertTravelerInputDataToEncodableTim(encodableTid); - try { - String xmlMsg; - DdsAdvisorySituationData asd = null; - if (!this.dataSigningEnabledSDW) { - // We need to send data UNSECURED, so we should try to build the ASD as well as - // MessageFrame - asd = TimTransmogrifier.buildASD(odeTID.getRequest()); - } - xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); - - if (xmlMsg != null) { - log.debug("XML representation: {}", xmlMsg); - - // Convert XML into ODE TIM JSON object and obfuscate RSU password - OdeTimData odeTimObj = OdeTimDataCreatorHelper.createOdeTimDataFromCreator(xmlMsg, timMetadata); - String j2735Tim = odeTimObj.toString(); - String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - - // publish Broadcast TIM to a J2735 compliant topic. - stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - - // publish J2735 TIM also to general un-filtered TIM topic with streamID as key - stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim); - - // Write XML to the encoder input topic at the end to ensure the correct order of operations to pair - // each message to an OdeTimJson streamId key - stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); - } - - serialIdOde.increment(); - serialIdJ2735.increment(); - } catch (JsonUtils.JsonUtilsException | XmlUtils.XmlUtilsException | TimTransmogrifierException e) { - String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); - log.error(errMsg, e); - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(JsonUtils.jsonKeyValue(ERRSTR, errMsg)); - } + log.debug("Encodable Traveler Information Data: {}", encodableTid); - INGEST_MONITOR.incrementTotalMessagesReceived(); - return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); + } catch (JsonUtilsException e) { + String errMsg = "Error converting to encodable TravelerInputData."; + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - /** - * Update an already-deposited TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PutMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity putTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); + try { + String xmlMsg; + DdsAdvisorySituationData asd = null; + if (!this.dataSigningEnabledSDW) { + // We need to send data UNSECURED, so we should try to build the ASD as well as + // MessageFrame + asd = TimTransmogrifier.buildASD(odeTID.getRequest()); + } + xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); + + if (xmlMsg != null) { + log.debug("XML representation: {}", xmlMsg); + + // Convert XML into ODE TIM JSON object and obfuscate RSU password + OdeTimData odeTimObj = OdeTimDataCreatorHelper.createOdeTimDataFromCreator( + xmlMsg, timMetadata); + String j2735Tim = odeTimObj.toString(); + String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); + + // publish Broadcast TIM to a J2735 compliant topic. + stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); + + // publish J2735 TIM also to general un-filtered TIM topic with streamID as key + stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), + obfuscatedJ2735Tim); + + // Write XML to the encoder input topic at the end to ensure the correct order + // of operations to pair + // each message to an OdeTimJson streamId key + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); + } + + serialIdOde.increment(); + serialIdJ2735.increment(); + } catch (JsonUtils.JsonUtilsException + | XmlUtils.XmlUtilsException + | TimTransmogrifierException e) { + String errMsg = "Error sending data to ASN.1 Encoder module: " + e.getMessage(); + log.error(errMsg, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body( + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } - /** - * Deposit a new TIM - * - * @param jsonString TIM in JSON - * @return list of success/failures - */ - @PostMapping(value = "/tim", produces = "application/json") - @CrossOrigin - public ResponseEntity postTim(@RequestBody String jsonString) { - - return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); - } + INGEST_MONITOR.incrementTotalMessagesReceived(); + return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(SUCCESS, "true")); + } + + /** + * Update an already-deposited TIM. + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PutMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity putTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.PUT); + } + + /** + * Deposit a new TIM. + * + * @param jsonString TIM in JSON + * @return list of success/failures + */ + @PostMapping(value = "/tim", produces = "application/json") + @CrossOrigin + public ResponseEntity postTim(@RequestBody String jsonString) { + + return depositTim(jsonString, ServiceRequest.OdeInternal.RequestVerb.POST); + } } diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml index b03a4ba6d..072580466 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml @@ -1,989 +1,989 @@ - - - timMsg - success - - - - unsecuredData - MessageFrame - UPER - - - us.dot.its.jpo.ode.model.OdeAsn1Payload - - adb022ef-9a97-4aa3-8bab-1fde55b620a1 - 1 - 0 - 0 - 0 - - 2024-12-05T10:21:33.228Z - 7 - 0 - - RSU - false - - - 001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600 - 172.18.0.1 - - - MessageFrame - - - 31 - - - 82 - 345337 - 4F4354455420535452 - IA5St - - - 29 - - - - - 4F43 - - 425 - 306216 - 31001 - 2 - 1 - - - IA5 - - 38149 - 48118 - - - -567387419 - -1717691068 - 53848 - - 15175 - - - - - - - 0001000000000000 - - - 0000000001000000 - - - - - -

- -686654332 - 1616508908 - 38736 -
- 3832 - - - - - - - -
- - I - - 64573 - 33281 - - - -714161321 - -1285139143 - 48475 - - 26805 - - - - - - - 0000001000000000 - - - 1 - - - - - - - -127947 - -120550 - - - - - - - - - - - - - - - - - - - - - - 101 - - - - - - 5822 - - - - - - 3017 - - - -8 - 62 - 35 - - 162 - 424 - - - - - - -998896073 - 735850714 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 3453 - - - - - - 7876 - - - -82 - - - - - - 2097 - - - - 264 - -269 - - - - - - 86161 - 20207 - - - - - - - - - - - - - - - - - - - -68 - - 245 - 247 - - - - - - -172 - 525 - - - - - - - - - - - - - - 206 - 144 - - - - - - -873243 - 1464496 - - - - - - - - - - - - - - - - 58 - 137 - 1 - 25 - - 414 - 181 - - - - - - - - - - IA5 - - 7296 - 1154 - - - 29950376 - 270580409 - 16367 - - 4926 - - - - - - - 0000000001000000 - - - 0000001000000000 - - - - 26482 - -
- 598135630 - 664850545 - 32186 -
- 3930 - - - -
-
-
-
- - IA5S - - 1582 - 46417 - - - -283655839 - -685153664 - 57976 - - 7235 - - - - - - - 0000000100000000 - - - 0000001000000000 - - - - - - - 581272185 - 1108489970 - 9059 - - 20085 - - - - - - - - - -605370079 - 829743521 - - - - - - - - - - - - - - - - - - - -87 - 4 - -167 - - 144 - 239 - - - - - - -605370079 - 829743521 - - - - - - - - - - - - - - - - - - - - - - - - 3517 - - - - -36 - -453 - - - - - - -605370079 - 829743521 - - - - - - - - - - - - - - - - - - - - - - - - 60 - -95 - - 463 - 57 - - - - - - - - - - - IA5 - - 11251 - 41890 - - - 385181606 - 1670812734 - 46812 - - 16153 - - - - - - - 0000001000000000 - - - 0000000001000000 - - - - 6004 - -
- -509239964 - 772185922 - 9413 -
- 1224 - - - -
-
-
-
- - 15 - 9 - - - - - 599 - - - - - IA5S - - - 11 - - - - - - - 634998835 - 313588249 - 50308 - - 0000000001000000 - - - - 4F43 - - - 3481 - 305174 - 24752 - 5 - 10 - - - I - - 44107 - 63537 - - - -419185997 - -533287210 - 51107 - - 25278 - - - - - - - 0000000000001000 - - - 8 - - - - - - - 900792217 - 448269129 - - - - - - - - - - - - - - - - - - - 18 - 9 - 24 - - 225 - -213 - - - - - - 900792217 - 448269129 - - - - - - - - - - - - - - - - - - - - -109 - 83 - - -31 - -482 - - - - - - -1370 - -1581 - - - - - - - - - - - - - - - - - - - - - - - - -121 - - 505 - 348 - - - - - - - - - - IA - - 30031 - 322 - - - -454547095 - 353479827 - 59458 - - 23566 - - - - - - - 0000000000100000 - - - 0000000000000010 - - - - 24321 - -
- -539150408 - -814772254 - 45059 -
- 1157 - - - -
-
-
-
- - IA5St - - 46088 - 60227 - - - -476956537 - 759386724 - 4505 - - 28846 - - - - - - - 0000000000000010 - - - 0010000000000000 - - - - 8084 - -
- -405703383 - -508985739 - 9512 -
- 2519 - - - -
-
-
-
-
- 11 - 23 - - - - - I - - - - - IA5St - - - - - IA5 - - - - - IA5St -
- - 13 - - - - - 4F43 - - 2776 - 408571 - 15957 - 5 - 6 - - - IA - - 62756 - 63693 - - - 424936826 - -1208779998 - 35858 - - 18563 - - - - - - - 0000000010000000 - - - 0010000000000000 - - - - 17158 - -
- 442482548 - -804103995 - 43319 -
- 1951 - - - -
-
-
-
- - IA5S - - 51032 - 30319 - - - -559743245 - 1697199162 - 46636 - - 5901 - - - - - - - 0000000000000100 - - - 0000001000000000 - - - - 28716 - -
- 707126893 - -77527193 - 35728 -
- 3343 - - - -
-
-
-
- - IA - - 23939 - 26592 - - - -328004279 - 88284632 - 45419 - - 15118 - - - - - - - 0000100000000000 - - - 1000000000000000 - - - - - -
- 171361070 - 1462406911 - 57912 -
- 3502 - - - -
- -
-
-
-
- 31 - 12 - - - - - 40721 - - - - - 36784 - - - - - IA5S - - - - - IA5 - - - - - 49435 - - - - - IA5S -
- - - - - - + + + timMsg + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + adb022ef-9a97-4aa3-8bab-1fde55b620a1 + 1 + 0 + 0 + 0 + + 2024-12-05T10:21:33.228Z + 7 + 0 + + RSU + false + + + 001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600 + 172.18.0.1 + + + MessageFrame + + + 31 + + + 82 + 345337 + 4F4354455420535452 + IA5St + + + 29 + + + + + 4F43 + + 425 + 306216 + 31001 + 2 + 1 + + + IA5 + + 38149 + 48118 + + + -567387419 + -1717691068 + 53848 + + 15175 + + + + + + + 0001000000000000 + + + 0000000001000000 + + + + + +
+ -686654332 + 1616508908 + 38736 +
+ 3832 + + + +
+ +
+
+
+ + I + + 64573 + 33281 + + + -714161321 + -1285139143 + 48475 + + 26805 + + + + + + + 0000001000000000 + + + 1 + + + + + + + -127947 + -120550 + + + + + + + + + + + + + + + + + + + + + + 101 + + + + + + 5822 + + + + + + 3017 + + + -8 + 62 + 35 + + 162 + 424 + + + + + + -998896073 + 735850714 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3453 + + + + + + 7876 + + + -82 + + + + + + 2097 + + + + 264 + -269 + + + + + + 86161 + 20207 + + + + + + + + + + + + + + + + + + + -68 + + 245 + 247 + + + + + + -172 + 525 + + + + + + + + + + + + + + 206 + 144 + + + + + + -873243 + 1464496 + + + + + + + + + + + + + + + + 58 + 137 + 1 + 25 + + 414 + 181 + + + + + + + + + + IA5 + + 7296 + 1154 + + + 29950376 + 270580409 + 16367 + + 4926 + + + + + + + 0000000001000000 + + + 0000001000000000 + + + + 26482 + +
+ 598135630 + 664850545 + 32186 +
+ 3930 + + + +
+
+
+
+ + IA5S + + 1582 + 46417 + + + -283655839 + -685153664 + 57976 + + 7235 + + + + + + + 0000000100000000 + + + 0000001000000000 + + + + + + + 581272185 + 1108489970 + 9059 + + 20085 + + + + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + -87 + 4 + -167 + + 144 + 239 + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + + + + + + 3517 + + + + -36 + -453 + + + + + + -605370079 + 829743521 + + + + + + + + + + + + + + + + + + + + + + + + 60 + -95 + + 463 + 57 + + + + + + + + + + + IA5 + + 11251 + 41890 + + + 385181606 + 1670812734 + 46812 + + 16153 + + + + + + + 0000001000000000 + + + 0000000001000000 + + + + 6004 + +
+ -509239964 + 772185922 + 9413 +
+ 1224 + + + +
+
+
+
+
+ 15 + 9 + + + + + 599 + + + + + IA5S +
+ + 11 + + + + + + + 634998835 + 313588249 + 50308 + + 0000000001000000 + + + + 4F43 + + + 3481 + 305174 + 24752 + 5 + 10 + + + I + + 44107 + 63537 + + + -419185997 + -533287210 + 51107 + + 25278 + + + + + + + 0000000000001000 + + + 8 + + + + + + + 900792217 + 448269129 + + + + + + + + + + + + + + + + + + + 18 + 9 + 24 + + 225 + -213 + + + + + + 900792217 + 448269129 + + + + + + + + + + + + + + + + + + + + -109 + 83 + + -31 + -482 + + + + + + -1370 + -1581 + + + + + + + + + + + + + + + + + + + + + + + + -121 + + 505 + 348 + + + + + + + + + + IA + + 30031 + 322 + + + -454547095 + 353479827 + 59458 + + 23566 + + + + + + + 0000000000100000 + + + 0000000000000010 + + + + 24321 + +
+ -539150408 + -814772254 + 45059 +
+ 1157 + + + +
+
+
+
+ + IA5St + + 46088 + 60227 + + + -476956537 + 759386724 + 4505 + + 28846 + + + + + + + 0000000000000010 + + + 0010000000000000 + + + + 8084 + +
+ -405703383 + -508985739 + 9512 +
+ 2519 + + + +
+
+
+
+
+ 11 + 23 + + + + + I + + + + + IA5St + + + + + IA5 + + + + + IA5St +
+ + 13 + + + + + 4F43 + + 2776 + 408571 + 15957 + 5 + 6 + + + IA + + 62756 + 63693 + + + 424936826 + -1208779998 + 35858 + + 18563 + + + + + + + 0000000010000000 + + + 0010000000000000 + + + + 17158 + +
+ 442482548 + -804103995 + 43319 +
+ 1951 + + + +
+
+
+
+ + IA5S + + 51032 + 30319 + + + -559743245 + 1697199162 + 46636 + + 5901 + + + + + + + 0000000000000100 + + + 0000001000000000 + + + + 28716 + +
+ 707126893 + -77527193 + 35728 +
+ 3343 + + + +
+
+
+
+ + IA + + 23939 + 26592 + + + -328004279 + 88284632 + 45419 + + 15118 + + + + + + + 0000100000000000 + + + 1000000000000000 + + + + + +
+ 171361070 + 1462406911 + 57912 +
+ 3502 + + + +
+ +
+
+
+
+ 31 + 12 + + + + + 40721 + + + + + 36784 + + + + + IA5S + + + + + IA5 + + + + + 49435 + + + + + IA5S +
+
+
+
+
+
+
\ No newline at end of file From 2fc4615d58f15cca093ff01489d110c0fa11feaf Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Thu, 5 Dec 2024 23:37:19 -0700 Subject: [PATCH 139/264] Update checkstyle xml --- checkstyle.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/checkstyle.xml b/checkstyle.xml index 842f596c3..fc79dfe84 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -27,6 +27,15 @@ + + + + + + + Date: Fri, 6 Dec 2024 00:47:03 -0700 Subject: [PATCH 140/264] Even more code styling changes --- .../us/dot/its/jpo/ode/util/XmlUtils.java | 81 ++++- .../dot/its/jpo/ode/model/OdeTimPayload.java | 35 ++- .../dot/its/jpo/ode/model/OdeTimDataTest.java | 52 ++-- .../test/resources/CVMessages/TIM_test.json | 1 + .../annotations/Asn1ParameterizedTypes.java | 97 +++--- .../ode/plugin/annotations/Asn1Property.java | 81 +++-- .../its/jpo/ode/plugin/utils/BitUtils.java | 39 ++- .../plugin/j2735/common/HeadingSliceTest.java | 47 +-- .../NodeAttributeSetLLTest.java | 48 +-- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 86 +++--- .../services/asn1/Asn1DecodedDataRouter.java | 277 ++++++++++-------- .../coder/OdeTimDataCreatorHelperTest.java | 37 +-- 12 files changed, 531 insertions(+), 350 deletions(-) create mode 100644 jpo-ode-core/src/test/resources/CVMessages/TIM_test.json diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java index 03b007a4d..9d7d746d9 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/util/XmlUtils.java @@ -1,22 +1,20 @@ /******************************************************************************* * Copyright 2018 572682 * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ -package us.dot.its.jpo.ode.util; -import org.json.JSONObject; -import org.json.XML; +package us.dot.its.jpo.ode.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; @@ -24,8 +22,16 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.fasterxml.jackson.dataformat.xml.XmlMapper.Builder; +import org.json.JSONObject; +import org.json.XML; +/** + * Utility class for XML manipulation. + */ public class XmlUtils { + /** + * Custom XML exception for handling XML parsing errors. + */ public static class XmlUtilsException extends Exception { private static final long serialVersionUID = 1L; @@ -50,6 +56,9 @@ public XmlUtilsException(String string, Exception e) { staticXmlMapper = builder.build(); } + /** + * Instantiates the XML utility as an object instead of using static methods. + */ public XmlUtils() { super(); var builder = new Builder(xmlMapper); @@ -74,6 +83,13 @@ public String toXml(Object o) throws JsonProcessingException { // } // } + /** + * Attempt to convert an XML String into the specified class type. + * + * @param xml The XML String value + * @param clazz The class type + * @return The deserialized object that is of type clazz + */ public Object fromXml(String xml, Class clazz) throws XmlUtilsException { try { return xmlMapper.readValue(xml, clazz); @@ -92,18 +108,26 @@ public Object fromXml(String xml, Class clazz) throws XmlUtilsException { * encoded to * 123. * Which is a more representative of the JSON ObjectNode. - * - * @param childKey: The key to be given to the child array object - * @param arrayNode: The array node to be embedded in a ObjectNode + * + * @param childKey The key to be given to the child array object + * @param arrayNode The array node to be embedded in a ObjectNode * @return OBjectNode representation of the given arrayNode redy to be converted * to XML */ - public static ObjectNode createEmbeddedJsonArrayForXmlConversion(String childKey, JsonNode arrayNode) { + public static ObjectNode createEmbeddedJsonArrayForXmlConversion(String childKey, + JsonNode arrayNode) { ObjectNode childNode = staticXmlMapper.createObjectNode(); childNode.set(childKey, arrayNode); return childNode; } + /** + * Find a component of an XML string by specifying the tag name. + * + * @param xml The XML String to be searched + * @param tagName The tag name to be identified + * @return The XML String only consisting of the tag and its children + */ public static String findXmlContentString(String xml, String tagName) { // Construct the start and end tag strings String startTag = "<" + tagName + ">"; @@ -129,6 +153,13 @@ public static String findXmlContentString(String xml, String tagName) { return xml.substring(startIndex, endIndex); } + /** + * Static method to attempt to serialize an object into XML. + * + * @param o The object to be serialized + * @return The serialized XML String + * @throws XmlUtilsException Throws an exception when failing to serialize the object + */ public static String toXmlStatic(Object o) throws XmlUtilsException { String xml; try { @@ -139,6 +170,14 @@ public static String toXmlStatic(Object o) throws XmlUtilsException { return xml; } + /** + * Static method to attempt to deserialize an XML String into a specified object type. + * + * @param xml The xml String to be deserialized + * @param clazz The class type + * @return The deserialized object of class type clazz + * @throws XmlUtilsException Throws an exception when failing to deserialize the XML String + */ public static Object fromXmlS(String xml, Class clazz) throws XmlUtilsException { try { return staticXmlMapper.readValue(xml, clazz); @@ -147,6 +186,13 @@ public static Object fromXmlS(String xml, Class clazz) throws XmlUtilsExcepti } } + /** + * Static method to attempt to transform an XML String into an ObjectNode. + * + * @param xml The xml String to be transformed + * @return An ObjectNode representing the XML + * @throws XmlUtilsException Throws an exception when failing to transform into an ObjectNode + */ public static ObjectNode toObjectNode(String xml) throws XmlUtilsException { try { JSONObject jsonObject = XML.toJSONObject(xml, true); @@ -166,6 +212,13 @@ public static ObjectNode toObjectNode(String xml) throws XmlUtilsException { } } + /** + * Static method to attempt to transform an XML String into a JSONObject. + * + * @param xml The xml String to be transformed + * @return A JSONObject representing the XML + * @throws XmlUtilsException Throws an exception when failing to transform into an JSONObject + */ public static JSONObject toJSONObject(String xml) throws XmlUtilsException { try { return XML.toJSONObject(xml, true); @@ -174,6 +227,14 @@ public static JSONObject toJSONObject(String xml) throws XmlUtilsException { } } + /** + * Get a specific JSON node from an XML String based on a field name. + * + * @param tree The xml String to be parsed + * @param fieldName The field name to be parsed for + * @return The JsonNode for the specified field name + * @throws XmlUtilsException Throws an exception when failing to parse the XML String + */ public static JsonNode getJsonNode(String tree, String fieldName) throws XmlUtilsException { JsonNode jsonNode; try { diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java index a0466e197..1a642b0ca 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java @@ -1,38 +1,43 @@ /******************************************************************************* * Copyright 2018 572682 * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.model; import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; import us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation; +/** + * ODE TIM payload class for both J2735 TravelerInformation and ODE + * TIM Creator OdeTravelerInformationMessage. + */ public class OdeTimPayload extends OdeMsgPayload { - private static final long serialVersionUID = 7061315628111448390L; + private static final long serialVersionUID = 7061315628111448390L; - public OdeTimPayload() { - this(new OdeTravelerInformationMessage()); - } + public OdeTimPayload() { + this(new OdeTravelerInformationMessage()); + } - public OdeTimPayload(OdeTravelerInformationMessage tim) { - super(tim); - this.setData(tim); - } + public OdeTimPayload(OdeTravelerInformationMessage tim) { + super(tim); + this.setData(tim); + } - public OdeTimPayload(TravelerInformation tim) { - super(tim); - this.setData(tim); - } + public OdeTimPayload(TravelerInformation tim) { + super(tim); + this.setData(tim); + } } diff --git a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java index 5a1b0debb..6a92a0ce7 100644 --- a/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java +++ b/jpo-ode-core/src/test/java/us/dot/its/jpo/ode/model/OdeTimDataTest.java @@ -1,36 +1,40 @@ package us.dot.its.jpo.ode.model; +import static org.junit.Assert.assertEquals; + 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 us.dot.its.jpo.ode.util.JsonUtils; - +import java.io.File; +import java.nio.file.Files; import java.util.Set; - import org.junit.jupiter.api.Test; +import us.dot.its.jpo.ode.util.JsonUtils; -import static org.junit.Assert.*; - +/** + * Tests for verifying the TIM schema is functional with the TIM JSON output. + */ public class OdeTimDataTest { - private static final String SCHEMA_VERSION = "7"; - private static final String ASN1_STRING = "001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100"; - - private static final String json = String.format("{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"89b9de68-7e91-4491-886f-d95276b67907\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-11-26T07:29:12.257Z\",\"schemaVersion\":7,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100\",\"originIp\":\"172.18.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Tim\",\"data\":{\"msgCnt\":\"1\",\"timeStamp\":\"417415\",\"packetID\":\"AD5DB73EE53601D49C\",\"dataFrames\":[{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"428312\",\"durationTime\":\"30\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"I_US-24_RSU_10.16.28.6\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1726,\"lat\":111}}},{\"delta\":{\"nodeLL5\":{\"lon\":1208360,\"lat\":77510}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"workZone\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"1025\"}}]}}},{\"notUsed\":\"0\",\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"viewAngle\":\"1111111111111111\",\"mutcdCode\":\"warning\"}},\"startYear\":\"2024\",\"startTime\":\"428312\",\"durationTime\":\"30\",\"priority\":\"5\",\"notUsed1\":\"0\",\"regions\":[{\"name\":\"I_US-24_RSU_10.16.28.6\",\"id\":{\"region\":0,\"id\":0},\"anchor\":{\"latitude\":38.8311689,\"longitude\":-104.8408366},\"laneWidth\":5000,\"directionality\":\"both\",\"closedPath\":false,\"description\":{\"path\":{\"scale\":0,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"nodeLL1\":{\"lon\":1726,\"lat\":111}}},{\"delta\":{\"nodeLL5\":{\"lon\":1208360,\"lat\":77510}}}]}}}}}],\"notUsed2\":\"0\",\"notUsed3\":\"0\",\"content\":{\"advisory\":{\"SEQUENCE\":[{\"item\":{\"itis\":\"770\"}}]}}}]}}}", SCHEMA_VERSION, ASN1_STRING); - - // - // Note that OdeTimData does not have annotations to support deserialization, so serialization/deserialization is not tested here. - // - - @Test - public void shouldValidateJson() throws Exception { - // Load json schema from resource - JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); - final JsonSchema schema = factory.getSchema(getClass().getClassLoader().getResource("schemas/schema-tim.json").toURI()); - final JsonNode node = (JsonNode)JsonUtils.fromJson(json, JsonNode.class); - Set validationMessages = schema.validate(node); - assertEquals(String.format("Json validation errors: %s", validationMessages), 0, validationMessages.size()); - } + @Test + public void shouldValidateJson() throws Exception { + // Load test JSON + String jsonFilePath = + "src/test/resources/CVMessages/TIM_test.json"; + File jsonFile = new File(jsonFilePath); + byte[] jsonData = Files.readAllBytes(jsonFile.toPath()); + String json = new String(jsonData); + + // Load JSON schema from resource + JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); + final JsonSchema schema = factory + .getSchema(getClass().getClassLoader().getResource("schemas/schema-tim.json").toURI()); + final JsonNode node = (JsonNode) JsonUtils.fromJson(json, 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/CVMessages/TIM_test.json b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json new file mode 100644 index 000000000..8d38a5a14 --- /dev/null +++ b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"89b9de68-7e91-4491-886f-d95276b67907","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-11-26T07:29:12.257Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735Tim","data":{"msgCnt":"1","timeStamp":"417415","packetID":"AD5DB73EE53601D49C","dataFrames":[{"notUsed":"0","frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":38.8311689,"longitude":-104.8408366},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startYear":"2024","startTime":"428312","durationTime":"30","priority":"5","notUsed1":"0","regions":[{"name":"I_US-24_RSU_10.16.28.6","id":{"region":0,"id":0},"anchor":{"latitude":38.8311689,"longitude":-104.8408366},"laneWidth":5000,"directionality":"both","closedPath":false,"description":{"path":{"scale":0,"offset":{"ll":{"nodes":[{"delta":{"nodeLL1":{"lon":1726,"lat":111}}},{"delta":{"nodeLL5":{"lon":1208360,"lat":77510}}}]}}}}}],"notUsed2":"0","notUsed3":"0","content":{"workZone":{"SEQUENCE":[{"item":{"itis":"1025"}}]}}},{"notUsed":"0","frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":38.8311689,"longitude":-104.8408366},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startYear":"2024","startTime":"428312","durationTime":"30","priority":"5","notUsed1":"0","regions":[{"name":"I_US-24_RSU_10.16.28.6","id":{"region":0,"id":0},"anchor":{"latitude":38.8311689,"longitude":-104.8408366},"laneWidth":5000,"directionality":"both","closedPath":false,"description":{"path":{"scale":0,"offset":{"ll":{"nodes":[{"delta":{"nodeLL1":{"lon":1726,"lat":111}}},{"delta":{"nodeLL5":{"lon":1208360,"lat":77510}}}]}}}}}],"notUsed2":"0","notUsed3":"0","content":{"advisory":{"SEQUENCE":[{"item":{"itis":"770"}}]}}}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java index 0777c6dd2..a877ec076 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1ParameterizedTypes.java @@ -7,59 +7,80 @@ /** * Annotation to specify how to deserialize an ASN1 parameterized type, which - * is represented by an abstract generic class in Java. Modeled after the JsonTypeInfo and - * JsonSubTypes annotations in Jackson, but adding the ability to specify that the + * is represented by an abstract generic class in Java. Modeled after the + * JsonTypeInfo and + * JsonSubTypes annotations in Jackson, but adding the ability to specify that + * the * id field is an integer, not restricted to being a string like in Jackson. + * * @author Ivan Yourshaw */ -@Target({ElementType.TYPE}) +@Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface Asn1ParameterizedTypes { - /** - * @return Name of the property used to determine which type to deserialize - */ - String idProperty(); + /** + * Id property. + * + * @return Name of the property used to determine which type to deserialize + */ + String idProperty(); - /** - * @return Type of the id property, which may be integer or string - */ - IdType idType(); + /** + * Type id property. + * + * @return Type of the id property, which may be integer or string + */ + IdType idType(); + + /** + * Name of the value property. + * + * @return Name of the value property containing the payload which can be + * various types + * depending on the generic type parameters. + */ + String valueProperty(); + /** + * Value property. + * + * @return Array of value types mapped to ids. + */ + Type[] value(); + + /** + * Id type enumeration. + */ + enum IdType { + INTEGER, + STRING + } + + /** + * Annotation to specify the type corresponding to an id. + */ + @interface Type { /** - * @return Name of the value property containing the payload which can be various types - * depending on the generic type parameters. + * Int id property. + * + * @return The id if it is an integer */ - String valueProperty(); + int intId() default -1; /** - * @return Array of value types mapped to ids. + * String id property. + * + * @return The id if it is a string */ - Type[] value(); - - enum IdType { - INTEGER, - STRING - } + String stringId() default ""; /** - * Annotation to specify the type corresponding to an id. + * Class value property. + * + * @return The specific class to deserialize to */ - @interface Type { - /** - * @return The id if it is an integer - */ - int intId() default -1; - - /** - * @return The id if it is a string - */ - String stringId() default ""; - - /** - * @return The specific class to deserialize to - */ - Class value(); - } + Class value(); + } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java index 2b5f58954..666434f8f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/annotations/Asn1Property.java @@ -6,42 +6,59 @@ import java.lang.annotation.Target; /** - * Provides metadata for a property of an Asn.1 class: components of Asn1Sequence, or alternatives of Asn1Choice. + * Provides metadata for a property of an Asn.1 class: components of + * Asn1Sequence, or alternatives of Asn1Choice. + * * @author Ivan Yourshaw */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Asn1Property { - /** - * @return Tag number indicating the canonical order of serialization - */ - int tag(); - - /** - * @return Name of the original non-normalized property. Not required if the Java property name is the same as - * the ASN.1 name. - */ - String name() default ""; - - /** - * @return True if the property is an extension, false if part of the root - */ - boolean extension() default false; - - /** - * @return True if the ASN.1 OPTIONAL marker is present - */ - boolean optional() default false; - - /** - * @return Default value specified by the ASN.1 DEFAULT marker. String can be converted to an integer for int types. - */ - String defaultValue() default ""; - - /** - * @return Indicates that the property is an ASN1 Open Type, so UPER encoding needs to use a length determinant - * as described in T-REC-X.691 (2021/2) section 11.2. - */ - boolean openType() default false; + /** + * Tag number property. + * + * @return Tag number indicating the canonical order of serialization + */ + int tag(); + + /** + * Name property. + * + * @return Name of the original non-normalized property. Not required if the + * Java property name is the same as + * the ASN.1 name. + */ + String name() default ""; + + /** + * Extensions present property. + * + * @return True if the property is an extension, false if part of the root + */ + boolean extension() default false; + + /** + * Optional field property. + * + * @return True if the ASN.1 OPTIONAL marker is present + */ + boolean optional() default false; + + /** + * Default value property. + * + * @return Default value specified by the ASN.1 DEFAULT marker. String can be + * converted to an integer for int types. + */ + String defaultValue() default ""; + + /** + * Open type property. + * + * @return Indicates that the property is an ASN1 Open Type, so UPER encoding + * needs to use a length determinant + * as described in T-REC-X.691 (2021/2) section 11.2. + */ + boolean openType() default false; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java index 901238fe3..69d7f4761 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/BitUtils.java @@ -1,22 +1,31 @@ package us.dot.its.jpo.ode.plugin.utils; - +/** + * Utility class containing static methods for bit manipulation. + */ public class BitUtils { - - public static byte reverseBits(final byte b) { - var reversedInt = Integer.reverse((int)b << 24) & 0xff; - return (byte)reversedInt; - } - - public static byte[] reverseBits(final byte[] bytes) { - byte[] reversed = new byte[bytes.length]; - for (int i = 0; i < bytes.length; i++) { - reversed[i] = reverseBits(bytes[i]); - } - return reversed; + /** + * Reverse bits in a single byte. + * + * @return The reversed byte. + */ + public static byte reverseBits(final byte b) { + var reversedInt = Integer.reverse((int) b << 24) & 0xff; + return (byte) reversedInt; + } + + /** + * Reverse bits in a byte array. + * + * @return The reversed byte array. + */ + public static byte[] reverseBits(final byte[] bytes) { + byte[] reversed = new byte[bytes.length]; + for (int i = 0; i < bytes.length; i++) { + reversed[i] = reverseBits(bytes[i]); } - + return reversed; + } } - diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java index 50d1cf62b..8da6c48bd 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java @@ -1,37 +1,44 @@ package us.dot.its.jpo.ode.plugin.j2735.common; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.*; - /** * Test serializing and deserializing a HeadingSlice bitstring to ODE JSON. */ public class HeadingSliceTest { - private final static ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = new ObjectMapper(); - @Test - public void testDeserializeJson() throws JsonProcessingException { - HeadingSlice hs = mapper.readValue(EXPECTED_JSON, HeadingSlice.class); - assertNotNull(hs); - for (int i = 0; i < hs.size(); i++) { - assertTrue(hs.get(i)); - } + @Test + public void testDeserializeJson() throws JsonProcessingException { + HeadingSlice hs = mapper.readValue(EXPECTED_JSON, HeadingSlice.class); + assertNotNull(hs); + for (int i = 0; i < hs.size(); i++) { + assertTrue(hs.get(i)); } + } - @Test - public void testSerializeJson() throws JsonProcessingException { - var hs = new HeadingSlice(); - for (int i = 0; i < hs.size(); i++) { - hs.set(i, true); - } - String json = mapper.writeValueAsString(hs); - assertEquals(EXPECTED_JSON, json); + @Test + public void testSerializeJson() throws JsonProcessingException { + var hs = new HeadingSlice(); + for (int i = 0; i < hs.size(); i++) { + hs.set(i, true); } + String json = mapper.writeValueAsString(hs); + assertEquals(EXPECTED_JSON, json); + } - private final static String EXPECTED_JSON = """ - {"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true,"from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true,"from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true,"from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true,"from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true,"from337-5to360-0degrees":true}"""; + private static final String EXPECTED_JSON = """ + {"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true, + "from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true, + "from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true, + "from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true, + "from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true, + "from337-5to360-0degrees":true}"""; } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java index 21fd63f21..56b627476 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java @@ -1,38 +1,40 @@ package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; -import static org.junit.jupiter.api.Assertions.*; - /** - * Test serializing and deserializing a NodeAttributeSetLL to and from ODE JSON + * Test serializing and deserializing a NodeAttributeSetLL to and from ODE JSON. */ public class NodeAttributeSetLLTest { - private final static ObjectMapper mapper = new ObjectMapper(); + private static final ObjectMapper mapper = new ObjectMapper(); - @Test - public void testDeserializeJson_dWidth_dElevation() throws JsonProcessingException { - final NodeAttributeSetLL nasll = mapper.readValue(DWITDH_DELEVATION_ONLY_JSON, NodeAttributeSetLL.class); - assertNotNull(nasll); - final long dElevation = nasll.getDElevation().getValue(); - assertEquals(424, dElevation); - final long dWidth = nasll.getDWidth().getValue(); - assertEquals(162, dWidth); - } + @Test + public void testDeserializeJson_dWidth_dElevation() throws JsonProcessingException { + final NodeAttributeSetLL nasll = mapper.readValue( + DWITDH_DELEVATION_ONLY_JSON, NodeAttributeSetLL.class); + assertNotNull(nasll); + final long dElevation = nasll.getDElevation().getValue(); + assertEquals(424, dElevation); + final long dWidth = nasll.getDWidth().getValue(); + assertEquals(162, dWidth); + } - @Test - public void testSerializeJson_dWidth_dElevation() throws JsonProcessingException { - final var nasll = new NodeAttributeSetLL(); - nasll.setDElevation(new Offset_B10(424L)); - nasll.setDWidth(new Offset_B10(162L)); - final String jsonResult = mapper.writeValueAsString(nasll); - assertEquals(DWITDH_DELEVATION_ONLY_JSON, jsonResult); - } + @Test + public void testSerializeJson_dWidth_dElevation() throws JsonProcessingException { + final var nasll = new NodeAttributeSetLL(); + nasll.setDElevation(new Offset_B10(424L)); + nasll.setDWidth(new Offset_B10(162L)); + final String jsonResult = mapper.writeValueAsString(nasll); + assertEquals(DWITDH_DELEVATION_ONLY_JSON, jsonResult); + } - private final static String DWITDH_DELEVATION_ONLY_JSON = """ - {"dWidth":162,"dElevation":424}"""; + private static final String DWITDH_DELEVATION_ONLY_JSON = """ + {"dWidth":162,"dElevation":424}"""; } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index 14d9eddc3..448d56036 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode; +import java.util.Properties; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.KafkaStreams; @@ -11,7 +12,6 @@ import org.apache.kafka.streams.state.QueryableStoreTypes; import org.apache.kafka.streams.state.Stores; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import java.util.Properties; /** * The OdeTimJsonTopology class sets up and manages a Kafka Streams topology @@ -23,46 +23,62 @@ @Slf4j public class OdeTimJsonTopology { - private final KafkaStreams streams; + private final KafkaStreams streams; - public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps, String topic) { + /** + * Constructs a new OdeTimJsonTopology. + * + * @param odeKafkaProps The Apache Kafka properties that will be used by the topology with Kafka. + * @param topic The Apache Kafka topic name. + **/ + public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps, String topic) { - Properties streamsProperties = new Properties(); - streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); - streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); - streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); - streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); + Properties streamsProperties = new Properties(); + streamsProperties.put(StreamsConfig.APPLICATION_ID_CONFIG, "KeyedOdeTimJson"); + streamsProperties.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, odeKafkaProps.getBrokers()); + streamsProperties.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); + streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); - if ("CONFLUENT".equals(odeKafkaProps.getKafkaType())) { - streamsProperties.put("sasl.jaas.config", odeKafkaProps.getConfluent().getSaslJaasConfig()); - } - streams = new KafkaStreams(buildTopology(topic), streamsProperties); - streams.setStateListener((newState, oldState) -> - log.info("Transitioning from {} to {}", oldState, newState) - ); - streams.start(); + if ("CONFLUENT".equals(odeKafkaProps.getKafkaType())) { + streamsProperties.put("sasl.jaas.config", odeKafkaProps.getConfluent().getSaslJaasConfig()); } + streams = new KafkaStreams(buildTopology(topic), streamsProperties); + streams.setStateListener((newState, oldState) -> + log.info("Transitioning from {} to {}", oldState, newState)); + streams.start(); + } - public void stop() { - log.info("Stopping Ode Tim Json Topology"); - streams.close(); - } + public void stop() { + log.info("Stopping Ode Tim Json Topology"); + streams.close(); + } - public boolean isRunning() { - return streams.state().isRunningOrRebalancing(); - } + public boolean isRunning() { + return streams.state().isRunningOrRebalancing(); + } - public Topology buildTopology(String topic) { - StreamsBuilder builder = new StreamsBuilder(); - builder.table(topic, Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); - return builder.build(); - } + /** + * Build the topology with a provided topic name. + * + * @param topic The topic name. + **/ + public Topology buildTopology(String topic) { + StreamsBuilder builder = new StreamsBuilder(); + builder.table(topic, Materialized.as( + Stores.inMemoryKeyValueStore("timjson-store"))); + return builder.build(); + } - public String query(String uuid) { - return (String) streams.store( - StoreQueryParameters.fromNameAndType( - "timjson-store", - QueryableStoreTypes.keyValueStore())) - .get(uuid); - } + /** + * Query the K-Table by a specified UUID. + * + * @param uuid The specified UUID to query for. + **/ + public String query(String uuid) { + return (String) streams.store( + StoreQueryParameters.fromNameAndType( + "timjson-store", + QueryableStoreTypes.keyValueStore())) + .get(uuid); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java index b70fe8ab7..3a1e9619b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java @@ -1,26 +1,32 @@ /******************************************************************************* * Copyright 2018 572682 * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.services.asn1; import lombok.extern.slf4j.Slf4j; import org.json.JSONObject; -import us.dot.its.jpo.ode.coder.*; +import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdePsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSpatDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSrmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeBsmData; @@ -31,141 +37,170 @@ import us.dot.its.jpo.ode.wrapper.MessageProducer; import us.dot.its.jpo.ode.wrapper.serdes.OdeBsmSerializer; +/** + * The Asn1DecodedDataRouter is responsible for routing all decoded messages + * from the topic.Asn1DecoderOutput Kafka topic to become deserialized POJOs + * and be written back to Kafka. + **/ @Slf4j public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor { - private final PojoTopics pojoTopics; - private final JsonTopics jsonTopics; - private final MessageProducer bsmProducer; - private final MessageProducer timProducer; - private final MessageProducer spatProducer; - private final MessageProducer ssmProducer; - private final MessageProducer srmProducer; - private final MessageProducer psmProducer; + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; + private final MessageProducer bsmProducer; + private final MessageProducer timProducer; + private final MessageProducer spatProducer; + private final MessageProducer ssmProducer; + private final MessageProducer srmProducer; + private final MessageProducer psmProducer; - public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics pojoTopics, JsonTopics jsonTopics) { - super(); + /** + * Creates a copy of Asn1DecodedDataRouter to actively consume from Kafka and write the + * deserialized output to the specified POJO and JSON topics. + * + * @param odeKafkaProperties The Kafka properties used to consume and produce to Kafka + * @param pojoTopics The specified POJO topics to write the deserialized POJO output to + * @param jsonTopics The specified JSON topics to write the deserialized JSON output to + **/ + public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics pojoTopics, + JsonTopics jsonTopics) { + super(); - this.pojoTopics = pojoTopics; - this.jsonTopics = jsonTopics; - this.bsmProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - null, - OdeBsmSerializer.class.getName(), - odeKafkaProperties.getDisabledTopics()); - this.timProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.spatProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.ssmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.srmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.psmProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - } + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + this.bsmProducer = new MessageProducer<>( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + null, + OdeBsmSerializer.class.getName(), + odeKafkaProperties.getDisabledTopics()); + this.timProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + this.spatProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + this.ssmProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + this.srmProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + this.psmProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + } - @Override - public Object process(String consumedData) { - try { - JSONObject consumed = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); - J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( - consumed.getJSONObject(AppContext.PAYLOAD_STRING) - .getJSONObject(AppContext.DATA_STRING) - .getJSONObject("MessageFrame") - .getInt("messageId") - ); + @Override + public Object process(String consumedData) { + try { + JSONObject consumed = XmlUtils.toJSONObject(consumedData).getJSONObject( + OdeAsn1Data.class.getSimpleName()); + J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( + consumed.getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING) + .getJSONObject("MessageFrame") + .getInt("messageId")); - RecordType recordType = RecordType - .valueOf(consumed.getJSONObject(AppContext.METADATA_STRING).getString("recordType")); + RecordType recordType = RecordType + .valueOf(consumed.getJSONObject(AppContext.METADATA_STRING).getString("recordType")); - switch (messageId) { - case BasicSafetyMessage -> routeBSM(consumedData, recordType); - case TravelerInformation -> routeTIM(consumedData, recordType); - case SPATMessage -> routeSPAT(consumedData, recordType); - case MAPMessage -> log.debug("MAP data processing no longer supported in this router."); - case SSMMessage -> routeSSM(consumedData, recordType); - case SRMMessage -> routeSRM(consumedData, recordType); - case PersonalSafetyMessage -> routePSM(consumedData, recordType); - case null, default -> log.warn("Unknown message type: {}", messageId); - } - } catch (Exception e) { - log.error("Failed to route received data: {}", consumedData, e); - } - return null; + switch (messageId) { + case BasicSafetyMessage -> routeBSM(consumedData, recordType); + case TravelerInformation -> routeTIM(consumedData, recordType); + case SPATMessage -> routeSPAT(consumedData, recordType); + case MAPMessage -> log.debug("MAP data processing no longer supported in this router."); + case SSMMessage -> routeSSM(consumedData, recordType); + case SRMMessage -> routeSRM(consumedData, recordType); + case PersonalSafetyMessage -> routePSM(consumedData, recordType); + case null, default -> log.warn("Unknown message type: {}", messageId); + } + } catch (Exception e) { + log.error("Failed to route received data: {}", consumedData, e); } + return null; + } - private void routePSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumedData).toString(); - if (recordType == RecordType.psmTx) { - psmProducer.send(pojoTopics.getTxPsm(), getRecord().key(), odePsmData); - } - // Send all PSMs also to OdePsmJson - psmProducer.send(jsonTopics.getPsm(), getRecord().key(), odePsmData); - log.debug("Submitted to PSM Pojo topic {}", jsonTopics.getPsm()); + private void routePSM(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumedData).toString(); + if (recordType == RecordType.psmTx) { + psmProducer.send(pojoTopics.getTxPsm(), getRecord().key(), odePsmData); } + // Send all PSMs also to OdePsmJson + psmProducer.send(jsonTopics.getPsm(), getRecord().key(), odePsmData); + log.debug("Submitted to PSM Pojo topic {}", jsonTopics.getPsm()); + } - private void routeSRM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumedData).toString(); - if (recordType == RecordType.srmTx) { - srmProducer.send(pojoTopics.getTxSrm(), getRecord().key(), odeSrmData); - } - // Send all SRMs also to OdeSrmJson - srmProducer.send(jsonTopics.getSrm(), getRecord().key(), odeSrmData); - log.debug("Submitted to SRM Pojo topic {}", jsonTopics.getSrm()); + private void routeSRM(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumedData).toString(); + if (recordType == RecordType.srmTx) { + srmProducer.send(pojoTopics.getTxSrm(), getRecord().key(), odeSrmData); } + // Send all SRMs also to OdeSrmJson + srmProducer.send(jsonTopics.getSrm(), getRecord().key(), odeSrmData); + log.debug("Submitted to SRM Pojo topic {}", jsonTopics.getSrm()); + } - private void routeSSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData).toString(); - if (recordType == RecordType.ssmTx) { - ssmProducer.send(pojoTopics.getSsm(), getRecord().key(), odeSsmData); - } - // Send all SSMs also to OdeSsmJson - ssmProducer.send(jsonTopics.getSsm(), getRecord().key(), odeSsmData); - log.debug("Submitted to SSM Pojo topic {}", jsonTopics.getSsm()); + private void routeSSM(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData).toString(); + if (recordType == RecordType.ssmTx) { + ssmProducer.send(pojoTopics.getSsm(), getRecord().key(), odeSsmData); } + // Send all SSMs also to OdeSsmJson + ssmProducer.send(jsonTopics.getSsm(), getRecord().key(), odeSsmData); + log.debug("Submitted to SSM Pojo topic {}", jsonTopics.getSsm()); + } - private void routeSPAT(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); - switch (recordType) { - case dnMsg -> spatProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeSpatData); - case rxMsg -> spatProducer.send(jsonTopics.getRxSpat(), getRecord().key(), odeSpatData); - case spatTx -> spatProducer.send(pojoTopics.getTxSpat(), getRecord().key(), odeSpatData); - default -> log.trace("Consumed SPAT data with record type: {}", recordType); - } - // Send all SPATs also to OdeSpatJson - spatProducer.send(jsonTopics.getSpat(), getRecord().key(), odeSpatData); - log.debug("Submitted to SPAT Pojo topic {}", jsonTopics.getSpat()); + private void routeSPAT(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); + switch (recordType) { + case dnMsg -> spatProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeSpatData); + case rxMsg -> spatProducer.send(jsonTopics.getRxSpat(), getRecord().key(), odeSpatData); + case spatTx -> spatProducer.send(pojoTopics.getTxSpat(), getRecord().key(), odeSpatData); + default -> log.trace("Consumed SPAT data with record type: {}", recordType); } + // Send all SPATs also to OdeSpatJson + spatProducer.send(jsonTopics.getSpat(), getRecord().key(), odeSpatData); + log.debug("Submitted to SPAT Pojo topic {}", jsonTopics.getSpat()); + } - private void routeTIM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - String odeTimData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(consumedData).toString(); - switch (recordType) { - case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); - case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); - default -> log.trace("Consumed TIM data with record type: {}", recordType); - } - // Send all TIMs also to OdeTimJson - timProducer.send(jsonTopics.getTim(), getRecord().key(), odeTimData); - log.debug("Submitted to TIM Pojo topic: {}", jsonTopics.getTim()); + private void routeTIM(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeTimData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded( + consumedData).toString(); + switch (recordType) { + case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); + case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); + default -> log.trace("Consumed TIM data with record type: {}", recordType); } + // Send all TIMs also to OdeTimJson + timProducer.send(jsonTopics.getTim(), getRecord().key(), odeTimData); + log.debug("Submitted to TIM Pojo topic: {}", jsonTopics.getTim()); + } - private void routeBSM(String consumedData, RecordType recordType) throws XmlUtils.XmlUtilsException { - // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the "recordType" - OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumedData); - switch (recordType) { - case bsmLogDuringEvent -> bsmProducer.send(pojoTopics.getBsmDuringEvent(), getRecord().key(), odeBsmData); - case rxMsg -> bsmProducer.send(pojoTopics.getRxBsm(), getRecord().key(), odeBsmData); - case bsmTx -> bsmProducer.send(pojoTopics.getTxBsm(), getRecord().key(), odeBsmData); - default -> log.trace("Consumed BSM data with record type: {}", recordType); - } - // Send all BSMs also to OdeBsmPojo - bsmProducer.send(pojoTopics.getBsm(), getRecord().key(), odeBsmData); - log.debug("Submitted to BSM Pojo topic {}", pojoTopics.getBsm()); + private void routeBSM(String consumedData, RecordType recordType) + throws XmlUtils.XmlUtilsException { + // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the + // "recordType" + OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumedData); + switch (recordType) { + case bsmLogDuringEvent -> bsmProducer.send(pojoTopics.getBsmDuringEvent(), + getRecord().key(), odeBsmData); + case rxMsg -> bsmProducer.send(pojoTopics.getRxBsm(), getRecord().key(), odeBsmData); + case bsmTx -> bsmProducer.send(pojoTopics.getTxBsm(), getRecord().key(), odeBsmData); + default -> log.trace("Consumed BSM data with record type: {}", recordType); } + // Send all BSMs also to OdeBsmPojo + bsmProducer.send(pojoTopics.getBsm(), getRecord().key(), odeBsmData); + log.debug("Submitted to BSM Pojo topic {}", pojoTopics.getBsm()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java index 87dce220f..37a491a76 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java @@ -6,37 +6,40 @@ import java.io.File; import java.io.IOException; import java.nio.file.Files; - import org.junit.jupiter.api.Test; - import us.dot.its.jpo.ode.model.OdeTimData; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +/** + * Tests for the OdeTimDataCreatorHelper class. + */ public class OdeTimDataCreatorHelperTest { @Test - public void testCreateOdeTimDataFromDecoded() throws IOException { - String xmlFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml"; + public void testCreateOdeTimDataFromDecoded() throws IOException { + String xmlFilePath = + "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml"; File xmlFile = new File(xmlFilePath); byte[] xmlData = Files.readAllBytes(xmlFile.toPath()); String xmlString = new String(xmlData); try { - XmlUtils.toObjectNode(xmlString); - } catch (XmlUtilsException e) { - fail("XML parsing error:" + e); - } + XmlUtils.toObjectNode(xmlString); + } catch (XmlUtilsException e) { + fail("XML parsing error:" + e); + } - String jsonFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json"; + String jsonFilePath = + "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json"; File jsonFile = new File(jsonFilePath); byte[] jsonData = Files.readAllBytes(jsonFile.toPath()); String expectedJsonString = new String(jsonData); - OdeTimData timData; - try { - timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); - assertEquals(expectedJsonString, timData.toString()); - } catch (XmlUtilsException e) { - e.printStackTrace(); - } + OdeTimData timData; + try { + timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); + assertEquals(expectedJsonString, timData.toString()); + } catch (XmlUtilsException e) { + e.printStackTrace(); + } - } + } } From fb4f577bb5353c76add1ee31568906cb12465c41 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Fri, 6 Dec 2024 01:11:26 -0700 Subject: [PATCH 141/264] Last bit of code styling. Please. --- .../plugin/j2735/builders/MAPBuilderTest.java | 67 +- .../services/asn1/Asn1EncodedDataRouter.java | 817 ++++++++++-------- 2 files changed, 490 insertions(+), 394 deletions(-) diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java index 3803a9bfc..a9c3118a9 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java @@ -3,27 +3,64 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; -import org.junit.jupiter.api.Test; - import com.fasterxml.jackson.databind.JsonNode; - +import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.plugin.j2735.J2735MAP; import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; +/** + * Testing the Map POJO builder classes. + */ public class MAPBuilderTest { - @Test - public void shouldTranslateMap() { + @Test + public void shouldTranslateMap() { + String mapXml = """ + us.dot.its.jpo.ode.model.OdeAsn1Payload + d07badec-84f0-48d8-8d4c-898fceaf4ecc1 + 000 + 2020-11-30T23:45:24.913657Z6 + 0 + false + mapTxsuccess + unsecuredData + MessageFrameUPER + V2XMessageFrame + 18 + 412 + 1561 + 389284111-772410713 + 100 + 000000000000000000 + 4324 + 4324 + + + """; - JsonNode jsonMap = null; - try { - jsonMap = XmlUtils.toObjectNode( - "us.dot.its.jpo.ode.model.OdeAsn1Payloadd07badec-84f0-48d8-8d4c-898fceaf4ecc10002020-11-30T23:45:24.913657Z60falsemapTxsuccessunsecuredDataMessageFrameUPERV2XMessageFrame184121561389284111-77241071310000000000000000000043244324"); - } catch (XmlUtilsException e) { - fail("XML parsing error:" + e); - } - J2735MAP actualMap = MAPBuilder.genericMAP(jsonMap.findValue("MapData")); - String expected = "{\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\":{\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\":{\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[{\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false,\"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicleTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false,\"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false,\"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false,\"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\":{\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\":false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\":false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\":{\"nodes\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}}]}}]}}]}}"; - assertEquals(expected, actualMap.toJson()); + JsonNode jsonMap = null; + try { + jsonMap = XmlUtils.toObjectNode(mapXml); + } catch (XmlUtilsException e) { + fail("XML parsing error:" + e); } + J2735MAP actualMap = MAPBuilder.genericMAP(jsonMap.findValue("MapData")); + String expected = """ + {\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\": + {\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\": + {\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[ + {\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false, + \"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicl + eTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false, + \"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false, + \"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false, + \"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\": + {\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\": + false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\": + false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\": + {\"nodes\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\": + {\"x\":43,\"y\":24}}}]}}]}}]}} + """; + assertEquals(expected, actualMap.toJson()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java index 95347eaa2..297dcaade 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1EncodedDataRouter.java @@ -1,20 +1,24 @@ /******************************************************************************* * Copyright 2018 572682 * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.services.asn1; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONException; @@ -22,9 +26,9 @@ import us.dot.its.jpo.ode.OdeTimJsonTopology; import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.eventlog.EventLogger; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.plugin.ServiceRequest; @@ -39,405 +43,460 @@ import us.dot.its.jpo.ode.wrapper.AbstractSubscriberProcessor; import us.dot.its.jpo.ode.wrapper.MessageProducer; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; - +/** + * The Asn1EncodedDataRouter is responsible for routing encoded TIM messages + * that are consumed from the Kafka topic.Asn1EncoderOutput topic and decide + * whether to route to the SDX or an RSU. + **/ @Slf4j public class Asn1EncodedDataRouter extends AbstractSubscriberProcessor { - private static final String BYTES = "bytes"; - private static final String MESSAGE_FRAME = "MessageFrame"; - private static final String ERROR_ON_SDX_DEPOSIT = "Error on SDX deposit."; + private static final String BYTES = "bytes"; + private static final String MESSAGE_FRAME = "MessageFrame"; + private static final String ERROR_ON_SDX_DEPOSIT = "Error on SDX deposit."; - public static class Asn1EncodedDataRouterException extends Exception { - private static final long serialVersionUID = 1L; + /** + * Exception for Asn1EncodedDataRouter specific failures. + */ + public static class Asn1EncodedDataRouterException extends Exception { + private static final long serialVersionUID = 1L; - public Asn1EncodedDataRouterException(String string) { - super(string); - } - } - - private final Asn1CoderTopics asn1CoderTopics; - private final JsonTopics jsonTopics; - - private final MessageProducer stringMsgProducer; - private final OdeTimJsonTopology odeTimJsonTopology; - private final Asn1CommandManager asn1CommandManager; - private final boolean dataSigningEnabledSDW; - private final boolean dataSigningEnabledRSU; - - public Asn1EncodedDataRouter(OdeKafkaProperties odeKafkaProperties, - Asn1CoderTopics asn1CoderTopics, - JsonTopics jsonTopics, - SDXDepositorTopics sdxDepositorTopics, - RsuProperties rsuProperties, - SecurityServicesProperties securityServicesProperties) { - super(); - - this.asn1CoderTopics = asn1CoderTopics; - this.jsonTopics = jsonTopics; - - this.stringMsgProducer = MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - - this.asn1CommandManager = new Asn1CommandManager(odeKafkaProperties, sdxDepositorTopics, rsuProperties, securityServicesProperties); - this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); - this.dataSigningEnabledRSU = securityServicesProperties.getIsRsuSigningEnabled(); - - odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties, jsonTopics.getTim()); + public Asn1EncodedDataRouterException(String string) { + super(string); } - - @Override - public Object process(String consumedData) { - try { - log.debug("Consumed: {}", consumedData); - JSONObject consumedObj = XmlUtils.toJSONObject(consumedData).getJSONObject(OdeAsn1Data.class.getSimpleName()); - - /* - * When receiving the 'rsus' in xml, since there is only one 'rsu' and - * there is no construct for array in xml, the rsus does not translate - * to an array of 1 element. The following workaround, resolves this - * issue. - */ - JSONObject metadata = consumedObj.getJSONObject(AppContext.METADATA_STRING); - - if (metadata.has(TimTransmogrifier.REQUEST_STRING)) { - JSONObject request = metadata.getJSONObject(TimTransmogrifier.REQUEST_STRING); - if (request.has(TimTransmogrifier.RSUS_STRING)) { - Object rsus = request.get(TimTransmogrifier.RSUS_STRING); - if (rsus instanceof JSONObject) { - JSONObject rsusIn = (JSONObject) request.get(TimTransmogrifier.RSUS_STRING); - if (rsusIn.has(TimTransmogrifier.RSUS_STRING)) { - Object rsu = rsusIn.get(TimTransmogrifier.RSUS_STRING); - JSONArray rsusOut = new JSONArray(); - if (rsu instanceof JSONArray) { - log.debug("Multiple RSUs exist in the request: {}", request); - JSONArray rsusInArray = (JSONArray) rsu; - for (int i = 0; i < rsusInArray.length(); i++) { - rsusOut.put(rsusInArray.get(i)); - } - request.put(TimTransmogrifier.RSUS_STRING, rsusOut); - } else if (rsu instanceof JSONObject) { - log.debug("Single RSU exists in the request: {}", request); - rsusOut.put(rsu); - request.put(TimTransmogrifier.RSUS_STRING, rsusOut); - } else { - log.debug("No RSUs exist in the request: {}", request); - request.remove(TimTransmogrifier.RSUS_STRING); - } - } - } + } + + private final Asn1CoderTopics asn1CoderTopics; + private final JsonTopics jsonTopics; + + private final MessageProducer stringMsgProducer; + private final OdeTimJsonTopology odeTimJsonTopology; + private final Asn1CommandManager asn1CommandManager; + private final boolean dataSigningEnabledSDW; + private final boolean dataSigningEnabledRSU; + + /** + * Instantiates the Asn1EncodedDataRouter to actively consume from Kafka and route the + * the encoded TIM messages to the SDX and RSUs. + * + * @param odeKafkaProperties The Kafka properties used to consume and produce to Kafka + * @param asn1CoderTopics The specified ASN1 Coder topics + * @param jsonTopics The specified JSON topics to write to + * @param sdxDepositorTopics The SDX depositor topics to write to + * @param rsuProperties The RSU properties to use + * @param securityServicesProperties The security services properties to use + **/ + public Asn1EncodedDataRouter(OdeKafkaProperties odeKafkaProperties, + Asn1CoderTopics asn1CoderTopics, + JsonTopics jsonTopics, + SDXDepositorTopics sdxDepositorTopics, + RsuProperties rsuProperties, + SecurityServicesProperties securityServicesProperties) { + super(); + + this.asn1CoderTopics = asn1CoderTopics; + this.jsonTopics = jsonTopics; + + this.stringMsgProducer = MessageProducer.defaultStringMessageProducer( + odeKafkaProperties.getBrokers(), + odeKafkaProperties.getKafkaType(), + odeKafkaProperties.getDisabledTopics()); + + this.asn1CommandManager = new Asn1CommandManager( + odeKafkaProperties, + sdxDepositorTopics, + rsuProperties, + securityServicesProperties); + this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); + this.dataSigningEnabledRSU = securityServicesProperties.getIsRsuSigningEnabled(); + + odeTimJsonTopology = new OdeTimJsonTopology(odeKafkaProperties, jsonTopics.getTim()); + } + + @Override + public Object process(String consumedData) { + try { + log.debug("Consumed: {}", consumedData); + JSONObject consumedObj = XmlUtils.toJSONObject(consumedData).getJSONObject( + OdeAsn1Data.class.getSimpleName()); + + /* + * When receiving the 'rsus' in xml, since there is only one 'rsu' and + * there is no construct for array in xml, the rsus does not translate + * to an array of 1 element. The following workaround, resolves this + * issue. + */ + JSONObject metadata = consumedObj.getJSONObject(AppContext.METADATA_STRING); + + if (metadata.has(TimTransmogrifier.REQUEST_STRING)) { + JSONObject request = metadata.getJSONObject(TimTransmogrifier.REQUEST_STRING); + if (request.has(TimTransmogrifier.RSUS_STRING)) { + Object rsus = request.get(TimTransmogrifier.RSUS_STRING); + if (rsus instanceof JSONObject) { + JSONObject rsusIn = (JSONObject) request.get(TimTransmogrifier.RSUS_STRING); + if (rsusIn.has(TimTransmogrifier.RSUS_STRING)) { + Object rsu = rsusIn.get(TimTransmogrifier.RSUS_STRING); + JSONArray rsusOut = new JSONArray(); + if (rsu instanceof JSONArray) { + log.debug("Multiple RSUs exist in the request: {}", request); + JSONArray rsusInArray = (JSONArray) rsu; + for (int i = 0; i < rsusInArray.length(); i++) { + rsusOut.put(rsusInArray.get(i)); } - - // Convert JSON to POJO - ServiceRequest servicerequest = getServicerequest(consumedObj); - - processEncodedTim(servicerequest, consumedObj); - } else { - throw new Asn1EncodedDataRouterException("Invalid or missing '" - + TimTransmogrifier.REQUEST_STRING + "' object in the encoder response"); - } - } catch (Exception e) { - String msg = "Error in processing received message from ASN.1 Encoder module: " + consumedData; - if (log.isDebugEnabled()) { - // print error message and stack trace - EventLogger.logger.error(msg, e); - log.error(msg, e); - } else { - // print error message only - EventLogger.logger.error(msg); - log.error(msg); + request.put(TimTransmogrifier.RSUS_STRING, rsusOut); + } else if (rsu instanceof JSONObject) { + log.debug("Single RSU exists in the request: {}", request); + rsusOut.put(rsu); + request.put(TimTransmogrifier.RSUS_STRING, rsusOut); + } else { + log.debug("No RSUs exist in the request: {}", request); + request.remove(TimTransmogrifier.RSUS_STRING); + } } + } } - return null; - } - - public ServiceRequest getServicerequest(JSONObject consumedObj) { - String sr = consumedObj.getJSONObject(AppContext.METADATA_STRING).getJSONObject(TimTransmogrifier.REQUEST_STRING).toString(); - log.debug("ServiceRequest: {}", sr); // Convert JSON to POJO - ServiceRequest serviceRequest = null; - try { - serviceRequest = (ServiceRequest) JsonUtils.fromJson(sr, ServiceRequest.class); - - } catch (Exception e) { - String errMsg = "Malformed JSON."; - EventLogger.logger.error(errMsg, e); - log.error(errMsg, e); - } - - return serviceRequest; + ServiceRequest servicerequest = getServicerequest(consumedObj); + + processEncodedTim(servicerequest, consumedObj); + } else { + throw new Asn1EncodedDataRouterException("Invalid or missing '" + + TimTransmogrifier.REQUEST_STRING + "' object in the encoder response"); + } + } catch (Exception e) { + String msg = "Error in processing received message from ASN.1 Encoder module: " + + consumedData; + if (log.isDebugEnabled()) { + // print error message and stack trace + EventLogger.logger.error(msg, e); + log.error(msg, e); + } else { + // print error message only + EventLogger.logger.error(msg); + log.error(msg); + } } - - public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { - - JSONObject dataObj = consumedObj.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING); - JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); - - // CASE 1: no SDW in metadata (SNMP deposit only) - // - sign MF - // - send to RSU - // CASE 2: SDW in metadata but no ASD in body (send back for another - // encoding) - // - sign MF - // - send to RSU - // - craft ASD object - // - publish back to encoder stream - // CASE 3: If SDW in metadata and ASD in body (double encoding complete) - // - send to SDX - - if (!dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { - log.debug("Unsigned message received"); - // We don't have ASD, therefore it must be just a MessageFrame that needs to be signed - // No support for unsecured MessageFrame only payload. - // Cases 1 & 2 - // Sign and send to RSUs - - JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); - - String hexEncodedTim = mfObj.getString(BYTES); - log.debug("Encoded message - phase 1: {}", hexEncodedTim); - //use Asnc1 library to decode the encoded tim returned from ASNC1; another class two blockers: decode the tim and decode the message-sign - - // Case 1: SNMP-deposit - if (dataSigningEnabledRSU && request.getRsus() != null) { - hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); - } else { - // if header is present, strip it - if (isHeaderPresent(hexEncodedTim)) { - String header = hexEncodedTim.substring(0, hexEncodedTim.indexOf("001F") + 4); - log.debug("Stripping header from unsigned message: {}", header); - hexEncodedTim = stripHeader(hexEncodedTim); - mfObj.remove(BYTES); - mfObj.put(BYTES, hexEncodedTim); - dataObj.remove(MESSAGE_FRAME); - dataObj.put(MESSAGE_FRAME, mfObj); - consumedObj.remove(AppContext.PAYLOAD_STRING); - consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); - } - } - - if (null != request.getSnmp() && null != request.getRsus() && null != hexEncodedTim) { - log.info("Sending message to RSUs..."); - asn1CommandManager.sendToRsus(request, hexEncodedTim); - } - - hexEncodedTim = mfObj.getString(BYTES); - - // Case 2: SDX-deposit - if (dataSigningEnabledSDW && request.getSdw() != null) { - hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); - } - - // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated - depositToFilteredTopic(metadataObj, hexEncodedTim); - if (request.getSdw() != null) { - // Case 2 only - - log.debug("Publishing message for round 2 encoding!"); - String xmlizedMessage = asn1CommandManager.packageSignedTimIntoAsd(request, hexEncodedTim); - - stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlizedMessage); - } - - } else { - //We have encoded ASD. It could be either UNSECURED or secured. - if (dataSigningEnabledSDW && request.getSdw() != null) { - log.debug("Signed message received. Depositing it to SDW."); - // We have a ASD with signed MessageFrame - // Case 3 - JSONObject asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); - try { - JSONObject deposit = new JSONObject(); - deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); - deposit.put("encodedMsg", asdObj.getString(BYTES)); - asn1CommandManager.depositToSdw(deposit.toString()); - } catch (JSONException | Asn1CommandManagerException e) { - String msg = ERROR_ON_SDX_DEPOSIT; - log.error(msg, e); - } - } else { - log.debug("Unsigned ASD received. Depositing it to SDW."); - //We have ASD with UNSECURED MessageFrame - processEncodedTimUnsecured(request, consumedObj); - } - } + return null; + } + + /** + * Gets the service request based on the consumed JSONObject. + * + * @param consumedObj The object to retrieve the service request for + * @return The service request + */ + public ServiceRequest getServicerequest(JSONObject consumedObj) { + String sr = consumedObj.getJSONObject(AppContext.METADATA_STRING).getJSONObject( + TimTransmogrifier.REQUEST_STRING).toString(); + log.debug("ServiceRequest: {}", sr); + + // Convert JSON to POJO + ServiceRequest serviceRequest = null; + try { + serviceRequest = (ServiceRequest) JsonUtils.fromJson(sr, ServiceRequest.class); + + } catch (Exception e) { + String errMsg = "Malformed JSON."; + EventLogger.logger.error(errMsg, e); + log.error(errMsg, e); } - public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consumedObj) { - // Send TIMs and record results - HashMap responseList = new HashMap<>(); - JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); - - JSONObject dataObj = consumedObj - .getJSONObject(AppContext.PAYLOAD_STRING) - .getJSONObject(AppContext.DATA_STRING); - - if (null != request.getSdw()) { - JSONObject asdObj = null; - if (dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { - asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); - } else { - log.error("ASD structure present in metadata but not in JSONObject!"); - } - - if (null != asdObj) { - String asdBytes = asdObj.getString(BYTES); - - try { - JSONObject deposit = new JSONObject(); - deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); - deposit.put("encodedMsg", asdBytes); - asn1CommandManager.depositToSdw(deposit.toString()); - log.info("SDX deposit successful."); - } catch (Exception e) { - String msg = ERROR_ON_SDX_DEPOSIT; - log.error(msg, e); - EventLogger.logger.error(msg, e); - } - - } else if (log.isErrorEnabled()) { // Added to avoid Sonar's "Invoke method(s) only conditionally." code smell - String msg = "ASN.1 Encoder did not return ASD encoding {}"; - EventLogger.logger.error(msg, consumedObj); - log.error(msg, consumedObj); - } + return serviceRequest; + } + + /** + * Process the signed encoded TIM message. + * + * @param request The service request + * @param consumedObj The consumed JSON object + */ + public void processEncodedTim(ServiceRequest request, JSONObject consumedObj) { + + JSONObject dataObj = consumedObj.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject( + AppContext.DATA_STRING); + JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); + + // CASE 1: no SDW in metadata (SNMP deposit only) + // - sign MF + // - send to RSU + // CASE 2: SDW in metadata but no ASD in body (send back for another + // encoding) + // - sign MF + // - send to RSU + // - craft ASD object + // - publish back to encoder stream + // CASE 3: If SDW in metadata and ASD in body (double encoding complete) + // - send to SDX + + if (!dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { + log.debug("Unsigned message received"); + // We don't have ASD, therefore it must be just a MessageFrame that needs to be + // signed + // No support for unsecured MessageFrame only payload. + // Cases 1 & 2 + // Sign and send to RSUs + + JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); + + String hexEncodedTim = mfObj.getString(BYTES); + log.debug("Encoded message - phase 1: {}", hexEncodedTim); + // use Asnc1 library to decode the encoded tim returned from ASNC1; another + // class two blockers: decode the tim and decode the message-sign + + // Case 1: SNMP-deposit + if (dataSigningEnabledRSU && request.getRsus() != null) { + hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); + } else { + // if header is present, strip it + if (isHeaderPresent(hexEncodedTim)) { + String header = hexEncodedTim.substring(0, hexEncodedTim.indexOf("001F") + 4); + log.debug("Stripping header from unsigned message: {}", header); + hexEncodedTim = stripHeader(hexEncodedTim); + mfObj.remove(BYTES); + mfObj.put(BYTES, hexEncodedTim); + dataObj.remove(MESSAGE_FRAME); + dataObj.put(MESSAGE_FRAME, mfObj); + consumedObj.remove(AppContext.PAYLOAD_STRING); + consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); } - - if (dataObj.has(MESSAGE_FRAME)) { - JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); - String encodedTim = mfObj.getString(BYTES); - - // Deposit encoded TIM to TMC-filtered topic if TMC-generated - depositToFilteredTopic(metadataObj, encodedTim); - - // if header is present, strip it - if (isHeaderPresent(encodedTim)) { - String header = encodedTim.substring(0, encodedTim.indexOf("001F") + 4); - log.debug("Stripping header from unsigned message: {}", header); - encodedTim = stripHeader(encodedTim); - mfObj.remove(BYTES); - mfObj.put(BYTES, encodedTim); - dataObj.remove(MESSAGE_FRAME); - dataObj.put(MESSAGE_FRAME, mfObj); - consumedObj.remove(AppContext.PAYLOAD_STRING); - consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); - } - - log.debug("Encoded message - phase 2: {}", encodedTim); - - // only send message to rsu if snmp, rsus, and message frame fields are present - if (null != request.getSnmp() && null != request.getRsus() && null != encodedTim) { - log.debug("Encoded message phase 3: {}", encodedTim); - asn1CommandManager.sendToRsus(request, encodedTim); - } + } + + if (null != request.getSnmp() && null != request.getRsus() && null != hexEncodedTim) { + log.info("Sending message to RSUs..."); + asn1CommandManager.sendToRsus(request, hexEncodedTim); + } + + hexEncodedTim = mfObj.getString(BYTES); + + // Case 2: SDX-deposit + if (dataSigningEnabledSDW && request.getSdw() != null) { + hexEncodedTim = signTIMAndProduceToExpireTopic(hexEncodedTim, consumedObj); + } + + // Deposit encoded & signed TIM to TMC-filtered topic if TMC-generated + depositToFilteredTopic(metadataObj, hexEncodedTim); + if (request.getSdw() != null) { + // Case 2 only + + log.debug("Publishing message for round 2 encoding!"); + String xmlizedMessage = asn1CommandManager.packageSignedTimIntoAsd(request, hexEncodedTim); + + stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlizedMessage); + } + + } else { + // We have encoded ASD. It could be either UNSECURED or secured. + if (dataSigningEnabledSDW && request.getSdw() != null) { + log.debug("Signed message received. Depositing it to SDW."); + // We have a ASD with signed MessageFrame + // Case 3 + JSONObject asdObj = dataObj.getJSONObject( + Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); + try { + JSONObject deposit = new JSONObject(); + deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); + deposit.put("encodedMsg", asdObj.getString(BYTES)); + asn1CommandManager.depositToSdw(deposit.toString()); + } catch (JSONException | Asn1CommandManagerException e) { + String msg = ERROR_ON_SDX_DEPOSIT; + log.error(msg, e); } - - log.info("TIM deposit response {}", responseList); + } else { + log.debug("Unsigned ASD received. Depositing it to SDW."); + // We have ASD with UNSECURED MessageFrame + processEncodedTimUnsecured(request, consumedObj); + } } + } + + /** + * Process the unsigned encoded TIM message. + * + * @param request The service request + * @param consumedObj The consumed JSON object + */ + public void processEncodedTimUnsecured(ServiceRequest request, JSONObject consumedObj) { + // Send TIMs and record results + HashMap responseList = new HashMap<>(); + JSONObject metadataObj = consumedObj.getJSONObject(AppContext.METADATA_STRING); + + JSONObject dataObj = consumedObj + .getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING); + + if (null != request.getSdw()) { + JSONObject asdObj = null; + if (dataObj.has(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING)) { + asdObj = dataObj.getJSONObject(Asn1CommandManager.ADVISORY_SITUATION_DATA_STRING); + } else { + log.error("ASD structure present in metadata but not in JSONObject!"); + } + + if (null != asdObj) { + String asdBytes = asdObj.getString(BYTES); - public String signTIMAndProduceToExpireTopic(String encodedTIM, JSONObject consumedObj) { - log.debug("Sending message for signature! "); - String base64EncodedTim = CodecUtils.toBase64( - CodecUtils.fromHex(encodedTIM)); - JSONObject metadataObjs = consumedObj.getJSONObject(AppContext.METADATA_STRING); - // get max duration time and convert from minutes to milliseconds (unsigned - // integer valid 0 to 2^32-1 in units of - // milliseconds.) from metadata - int maxDurationTime = Integer.valueOf(metadataObjs.get("maxDurationTime").toString()) * 60 * 1000; - String timpacketID = metadataObjs.getString("odePacketID"); - String timStartDateTime = metadataObjs.getString("odeTimStartDateTime"); - String signedResponse = asn1CommandManager.sendForSignature(base64EncodedTim, maxDurationTime); try { - String hexEncodedTim = CodecUtils.toHex( - CodecUtils.fromBase64( - JsonUtils.toJSONObject(JsonUtils.toJSONObject(signedResponse).getString("result")).getString("message-signed"))); - - JSONObject timWithExpiration = new JSONObject(); - timWithExpiration.put("packetID", timpacketID); - timWithExpiration.put("startDateTime", timStartDateTime); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - try { - JSONObject jsonResult = JsonUtils - .toJSONObject((JsonUtils.toJSONObject(signedResponse).getString("result"))); - // messageExpiry uses unit of seconds - long messageExpiry = Long.parseLong(jsonResult.getString("message-expiry")); - timWithExpiration.put("expirationDate", dateFormat.format(new Date(messageExpiry * 1000))); - } catch (Exception e) { - log.error("Unable to get expiration date from signed messages response ", e); - timWithExpiration.put("expirationDate", "null"); - } - - try { - Date parsedtimTimeStamp = dateFormat.parse(timStartDateTime); - Date requiredExpirationDate = new Date(); - requiredExpirationDate.setTime(parsedtimTimeStamp.getTime() + maxDurationTime); - timWithExpiration.put("requiredExpirationDate", dateFormat.format(requiredExpirationDate)); - } catch (Exception e) { - log.error("Unable to parse requiredExpirationDate ", e); - timWithExpiration.put("requiredExpirationDate", "null"); - } - //publish to Tim expiration kafka - stringMsgProducer.send(jsonTopics.getTimCertExpiration(), null, - timWithExpiration.toString()); - - return hexEncodedTim; - - } catch (JsonUtilsException e1) { - log.error("Unable to parse signed message response ", e1); + JSONObject deposit = new JSONObject(); + deposit.put("estimatedRemovalDate", request.getSdw().getEstimatedRemovalDate()); + deposit.put("encodedMsg", asdBytes); + asn1CommandManager.depositToSdw(deposit.toString()); + log.info("SDX deposit successful."); + } catch (Exception e) { + String msg = ERROR_ON_SDX_DEPOSIT; + log.error(msg, e); + EventLogger.logger.error(msg, e); } - return encodedTIM; - } - /** - * Checks if header is present in encoded message - */ - private boolean isHeaderPresent(String encodedTim) { - return encodedTim.indexOf("001F") > 0; + } else if (log.isErrorEnabled()) { + // Added to avoid Sonar's "Invoke method(s) only conditionally." code smell + String msg = "ASN.1 Encoder did not return ASD encoding {}"; + EventLogger.logger.error(msg, consumedObj); + log.error(msg, consumedObj); + } } - /** - * Strips header from unsigned message (all bytes before 001F hex value) - */ - private String stripHeader(String encodedUnsignedTim) { - String toReturn = ""; - // find 001F hex value - int index = encodedUnsignedTim.indexOf("001F"); - if (index == -1) { - log.warn("No '001F' hex value found in encoded message"); - return encodedUnsignedTim; - } - // strip everything before 001F - toReturn = encodedUnsignedTim.substring(index); - return toReturn; + if (dataObj.has(MESSAGE_FRAME)) { + JSONObject mfObj = dataObj.getJSONObject(MESSAGE_FRAME); + String encodedTim = mfObj.getString(BYTES); + + // Deposit encoded TIM to TMC-filtered topic if TMC-generated + depositToFilteredTopic(metadataObj, encodedTim); + + // if header is present, strip it + if (isHeaderPresent(encodedTim)) { + String header = encodedTim.substring(0, encodedTim.indexOf("001F") + 4); + log.debug("Stripping header from unsigned message: {}", header); + encodedTim = stripHeader(encodedTim); + mfObj.remove(BYTES); + mfObj.put(BYTES, encodedTim); + dataObj.remove(MESSAGE_FRAME); + dataObj.put(MESSAGE_FRAME, mfObj); + consumedObj.remove(AppContext.PAYLOAD_STRING); + consumedObj.put(AppContext.PAYLOAD_STRING, dataObj); + } + + log.debug("Encoded message - phase 2: {}", encodedTim); + + // only send message to rsu if snmp, rsus, and message frame fields are present + if (null != request.getSnmp() && null != request.getRsus() && null != encodedTim) { + log.debug("Encoded message phase 3: {}", encodedTim); + asn1CommandManager.sendToRsus(request, encodedTim); + } } - private void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim) { - try { - String generatedBy = metadataObj.getString("recordGeneratedBy"); - String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); - if (!generatedBy.equalsIgnoreCase("TMC")) { - log.debug("Not a TMC-generated TIM. Skipping deposit to TMC-filtered topic."); - return; - } - - String timString = odeTimJsonTopology.query(streamId); - if (timString != null) { - // Set ASN1 data in TIM metadata - JSONObject timJSON = new JSONObject(timString); - JSONObject metadataJSON = timJSON.getJSONObject("metadata"); - metadataJSON.put("asn1", hexEncodedTim); - timJSON.put("metadata", metadataJSON); - - // Send the message w/ asn1 data to the TMC-filtered topic - stringMsgProducer.send(jsonTopics.getTimTmcFiltered(), null, timJSON.toString()); - } - } catch (JSONException e) { - log.error("Error while fetching recordGeneratedBy field: {}", e.getMessage()); - } catch (Exception e) { - log.error("Error while updating TIM: {}", e.getMessage()); - } + log.info("TIM deposit response {}", responseList); + } + + /** + * Sign the encoded TIM message and write to Kafka with an expiration time. + * + * @param encodedTIM The encoded TIM message to be signed + * @param consumedObj The JSON object to be consumed + * @return The String representation of the encodedTim payload + */ + public String signTIMAndProduceToExpireTopic(String encodedTIM, JSONObject consumedObj) { + log.debug("Sending message for signature! "); + String base64EncodedTim = CodecUtils.toBase64( + CodecUtils.fromHex(encodedTIM)); + JSONObject metadataObjs = consumedObj.getJSONObject(AppContext.METADATA_STRING); + // get max duration time and convert from minutes to milliseconds (unsigned + // integer valid 0 to 2^32-1 in units of + // milliseconds.) from metadata + int maxDurationTime = Integer.valueOf(metadataObjs.get("maxDurationTime").toString()) + * 60 * 1000; + String timpacketID = metadataObjs.getString("odePacketID"); + String timStartDateTime = metadataObjs.getString("odeTimStartDateTime"); + String signedResponse = asn1CommandManager.sendForSignature(base64EncodedTim, maxDurationTime); + try { + final String hexEncodedTim = CodecUtils.toHex( + CodecUtils.fromBase64( + JsonUtils.toJSONObject(JsonUtils.toJSONObject(signedResponse).getString("result")) + .getString("message-signed"))); + + JSONObject timWithExpiration = new JSONObject(); + timWithExpiration.put("packetID", timpacketID); + timWithExpiration.put("startDateTime", timStartDateTime); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); + try { + JSONObject jsonResult = JsonUtils + .toJSONObject((JsonUtils.toJSONObject(signedResponse).getString("result"))); + // messageExpiry uses unit of seconds + long messageExpiry = Long.parseLong(jsonResult.getString("message-expiry")); + timWithExpiration.put("expirationDate", dateFormat.format(new Date(messageExpiry * 1000))); + } catch (Exception e) { + log.error("Unable to get expiration date from signed messages response ", e); + timWithExpiration.put("expirationDate", "null"); + } + + try { + Date parsedtimTimeStamp = dateFormat.parse(timStartDateTime); + Date requiredExpirationDate = new Date(); + requiredExpirationDate.setTime(parsedtimTimeStamp.getTime() + maxDurationTime); + timWithExpiration.put("requiredExpirationDate", dateFormat.format(requiredExpirationDate)); + } catch (Exception e) { + log.error("Unable to parse requiredExpirationDate ", e); + timWithExpiration.put("requiredExpirationDate", "null"); + } + // publish to Tim expiration kafka + stringMsgProducer.send(jsonTopics.getTimCertExpiration(), null, + timWithExpiration.toString()); + + return hexEncodedTim; + + } catch (JsonUtilsException e1) { + log.error("Unable to parse signed message response ", e1); + } + return encodedTIM; + } + + /** + * Checks if header is present in encoded message. + */ + private boolean isHeaderPresent(String encodedTim) { + return encodedTim.indexOf("001F") > 0; + } + + /** + * Strips header from unsigned message (all bytes before 001F hex value). + */ + private String stripHeader(String encodedUnsignedTim) { + String toReturn = ""; + // find 001F hex value + int index = encodedUnsignedTim.indexOf("001F"); + if (index == -1) { + log.warn("No '001F' hex value found in encoded message"); + return encodedUnsignedTim; + } + // strip everything before 001F + toReturn = encodedUnsignedTim.substring(index); + return toReturn; + } + + private void depositToFilteredTopic(JSONObject metadataObj, String hexEncodedTim) { + try { + String generatedBy = metadataObj.getString("recordGeneratedBy"); + String streamId = metadataObj.getJSONObject("serialId").getString("streamId"); + if (!generatedBy.equalsIgnoreCase("TMC")) { + log.debug("Not a TMC-generated TIM. Skipping deposit to TMC-filtered topic."); + return; + } + + String timString = odeTimJsonTopology.query(streamId); + if (timString != null) { + // Set ASN1 data in TIM metadata + JSONObject timJSON = new JSONObject(timString); + JSONObject metadataJSON = timJSON.getJSONObject("metadata"); + metadataJSON.put("asn1", hexEncodedTim); + timJSON.put("metadata", metadataJSON); + + // Send the message w/ asn1 data to the TMC-filtered topic + stringMsgProducer.send(jsonTopics.getTimTmcFiltered(), null, timJSON.toString()); + } + } catch (JSONException e) { + log.error("Error while fetching recordGeneratedBy field: {}", e.getMessage()); + } catch (Exception e) { + log.error("Error while updating TIM: {}", e.getMessage()); } + } } From abce4e5fad300b4ee4d346f83ae7a9006d2879ef Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Fri, 6 Dec 2024 04:14:28 -0700 Subject: [PATCH 142/264] Update the TIM schema and resolve some test issues --- .../main/resources/schemas/schema-tim.json | 1154 +++++++++++------ .../test/resources/CVMessages/TIM_test.json | 2 +- .../TravelerDataFrame.java | 4 +- .../plugin/j2735/builders/MAPBuilderTest.java | 16 +- .../plugin/j2735/common/HeadingSliceTest.java | 7 +- .../OdeTimDataCreatorHelper_TIM_JSON.json | 2 +- .../OdeTimDataCreatorHelper_TIM_XER.xml | 5 +- 7 files changed, 776 insertions(+), 414 deletions(-) diff --git a/jpo-ode-core/src/main/resources/schemas/schema-tim.json b/jpo-ode-core/src/main/resources/schemas/schema-tim.json index d539c00e9..9076ee5c3 100644 --- a/jpo-ode-core/src/main/resources/schemas/schema-tim.json +++ b/jpo-ode-core/src/main/resources/schemas/schema-tim.json @@ -260,10 +260,10 @@ "type": "object", "properties": { "nwCorner": { - "$ref": "#/$defs/OdePosition3D" + "$ref": "#/$defs/Position3D" }, "seCorner": { - "$ref": "#/$defs/OdePosition3D" + "$ref": "#/$defs/Position3D" } }, "required": [ @@ -317,7 +317,7 @@ "type": "object", "properties": { "data": { - "$ref": "#/$defs/J2735Tim" + "$ref": "#/$defs/TravelerInformation" }, "dataType": { "type": "string" @@ -328,11 +328,11 @@ "dataType" ] }, - "J2735Tim": { + "TravelerInformation": { "type": "object", "properties": { "timeStamp": { - "type": "string" + "type": "number" }, "packetID": { "type": "string" @@ -344,12 +344,12 @@ "type": "array", "prefixItems": [ { - "$ref": "#/$defs/J2735TravelerDataFrame" + "$ref": "#/$defs/TravelerDataFrame" } ] }, "msgCnt": { - "type": "string" + "type": "number" } }, "required": [ @@ -357,11 +357,11 @@ "msgCnt" ] }, - "J2735TravelerDataFrame": { + "TravelerDataFrame": { "type": "object", "properties": { "notUsed": { - "type": "string" + "type": "number" }, "frameType": { "enum": [ @@ -385,41 +385,49 @@ ] }, { - "$ref": "#/$defs/J2735DF_MsgId_RoadSignId" + "type": "object", + "properties": { + "roadSignID": { + "$ref": "#/$defs/RoadSignID" + } + }, + "required": [ + "roadSignID" + ] } ] }, "startYear": { - "type": "string" + "type": "number" }, "startTime": { - "type": "string" + "type": "number" }, "durationTime": { - "type": "string" + "type": "number" }, "priority": { - "type": "string" + "type": "number" }, "notUsed1": { - "type": "string" + "type": "number" }, "regions": { "type": "array", "prefixItems": [ { - "$ref": "#/$defs/J2735DF_GeographicalPath" + "$ref": "#/$defs/GeographicalPath" } ] }, "notUsed2": { - "type": "string" + "type": "number" }, "notUsed3": { - "type": "string" + "type": "number" }, "content": { - "$ref": "#/$defs/J2735DF_Content" + "$ref": "#/$defs/ContentChoice" }, "url": { "type": "string" @@ -439,84 +447,153 @@ "content" ] }, - "J2735DF_MsgId_RoadSignId": { + "RoadSignID": { "type": "object", "properties": { - "roadSignID": { - "type": "object", - "properties": { - "position": { - "$ref": "#/$defs/OdePosition3D" - }, - "viewAngle": { - "type": "string" - }, - "mutcdCode": { - "enum": [ - "none", - "regulatory", - "warning", - "maintenance", - "motoristService", - "guide", - "rec" - ] - } - }, - "required": [ - "position", - "viewAngle" + "position": { + "$ref": "#/$defs/Position3D" + }, + "viewAngle": { + "$ref": "#/$defs/HeadingSlice" + }, + "mutcdCode": { + "enum": [ + "none", + "regulatory", + "warning", + "maintenance", + "motoristService", + "guide", + "rec" ] + }, + "crc": { + "type": "string" + } + }, + "required": [ + "position", + "viewAngle" + ] + }, + "HeadingSlice": { + "type": "object", + "properties": { + "from000-0to022-5degrees": { + "type": "boolean" + }, + "from022-5to045-0degrees": { + "type": "boolean" + }, + "from045-0to067-5degrees": { + "type": "boolean" + }, + "from067-5to090-0degrees": { + "type": "boolean" + }, + "from090-0to112-5degrees": { + "type": "boolean" + }, + "from112-5to135-0degrees": { + "type": "boolean" + }, + "from135-0to157-5degrees": { + "type": "boolean" + }, + "from157-5to180-0degrees": { + "type": "boolean" + }, + "from180-0to202-5degrees": { + "type": "boolean" + }, + "from202-5to225-0degrees": { + "type": "boolean" + }, + "from225-0to247-5degrees": { + "type": "boolean" + }, + "from247-5to270-0degrees": { + "type": "boolean" + }, + "from270-0to292-5degrees": { + "type": "boolean" + }, + "from292-5to315-0degrees": { + "type": "boolean" + }, + "from315-0to337-5degrees": { + "type": "boolean" + }, + "from337-5to360-0degrees": { + "type": "boolean" } }, "required": [ - "roadSignID" + "from000-0to022-5degrees", + "from022-5to045-0degrees", + "from045-0to067-5degrees", + "from067-5to090-0degrees", + "from090-0to112-5degrees", + "from112-5to135-0degrees", + "from135-0to157-5degrees", + "from157-5to180-0degrees", + "from180-0to202-5degrees", + "from202-5to225-0degrees", + "from225-0to247-5degrees", + "from247-5to270-0degrees", + "from270-0to292-5degrees", + "from292-5to315-0degrees", + "from315-0to337-5degrees", + "from337-5to360-0degrees" ] }, - "J2735DF_GeographicalPath": { + "GeographicalPath": { "type": "object", "properties": { "name": { "type": "string" }, "id": { - "$ref": "#/$defs/J2735RoadSegmentReferenceID" + "$ref": "#/$defs/RoadSegmentReferenceID" }, "anchor": { - "$ref": "#/$defs/OdePosition3D" + "$ref": "#/$defs/Position3D" }, "laneWidth": { "type": "number" }, "directionality": { - "enum": [ - "unavailable", - "forward", - "reverse", - "both" - ] + "$ref": "#/$defs/DirectionOfUse" }, "closedPath": { "type": "boolean" }, "direction": { - "type": "string" + "$ref": "#/$defs/HeadingSlice" }, "description": { - "$ref": "#/$defs/J2735DF_Regions_Description" + "$ref": "#/$defs/DescriptionChoice" } }, "required": [ "description" ] }, - "J2735DF_Regions_Description": { + "DirectionOfUse": { + "enum": [ + "unavailable", + "forward", + "reverse", + "both" + ] + }, + "DescriptionChoice": { "oneOf": [ { "type": "object", "properties": { "path": { - "$ref": "#/$defs/J2735OffsetSystem" + "$ref": "#/$defs/OffsetSystem" } }, "required": [ @@ -527,76 +604,105 @@ "type": "object", "properties": { "geometry": { - "$ref": "#/$defs/J2735GeometricProjection" + "$ref": "#/$defs/GeometricProjection" } }, "required": [ "geometry" ] + }, + { + "type": "object", + "properties": { + "oldRegion": { + "$ref": "#/$defs/ValidRegion" + } + }, + "required": [ + "oldRegion" + ] } ] }, - "J2735OffsetSystem": { + "OffsetSystem": { "type": "object", "properties": { "scale": { "type": "number" }, "offset": { - "oneOf": [ - { - "type": "object", - "properties": { - "xy": { - "$ref": "#/$defs/J2735NodeListXY" - } - }, - "required": [ - "xy" - ] - }, - { - "type": "object", - "properties": { - "ll": { - "$ref": "#/$defs/J2735NodeListLL" - } - }, - "required": [ - "ll" - ] - } - ] + "$ref": "#/$defs/OffsetChoice" } }, "required": [ "offset" ] }, - "J2735NodeListXY": { - "type": "object", - "properties": { - "nodes": { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735NodeXY" + "OffsetChoice": { + "oneOf": [ + { + "type": "object", + "properties": { + "xy": { + "$ref": "#/$defs/NodeListXY" + } + }, + "required": [ + "xy" + ] + }, + { + "type": "object", + "properties": { + "ll": { + "$ref": "#/$defs/NodeListLL" } + }, + "required": [ + "ll" + ] + } + ] + }, + "NodeListXY": { + "oneOf": [ + { + "type": "object", + "properties": { + "nodes": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/NodeXY" + } + ] + } + }, + "required": [ + "nodes" + ] + }, + { + "type": "object", + "properties": { + "computed": { + "$ref": "#/$defs/ComputedLane" + } + }, + "required": [ + "computed" ] } - }, - "required": [ - "nodes" ] }, - "J2735NodeListLL": { + "NodeListLL": { "type": "object", "properties": { "nodes": { "type": "array", "prefixItems": [ { - "$ref": "#/$defs/J2735NodeLL" + "$ref": "#/$defs/NodeLL" } ] } @@ -605,504 +711,778 @@ "nodes" ] }, - "J2735NodeXY": { + "NodeXY": { "type": "object", "properties": { "delta": { - "oneOf": [ - { - "type": "object", - "properties": { - "nodeXY1": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY1" - ] - }, - { - "type": "object", - "properties": { - "nodeXY2": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY2" - ] - }, - { - "type": "object", - "properties": { - "nodeXY3": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY3" - ] - }, - { - "type": "object", - "properties": { - "nodeXY4": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY4" - ] - }, - { - "type": "object", - "properties": { - "nodeXY5": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY5" - ] - }, - { - "type": "object", - "properties": { - "nodeXY6": { - "$ref": "#/$defs/J2735NodeXYDelta" - } - }, - "required": [ - "nodeXY6" - ] - }, - { - "type": "object", - "properties": { - "nodeLatLon": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLatLon" - ] - } - ] + "$ref": "#/$defs/NodeOffsetPointXY" + }, + "attributes": { + "$ref": "#/$defs/NodeAttributeSet" } }, "required": [ "delta" ] }, - "J2735NodeLL": { - "type": "object", - "properties": { - "delta": { - "oneOf": [ - { - "type": "object", - "properties": { - "nodeLL1": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL1" - ] - }, - { - "type": "object", - "properties": { - "nodeLL2": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL2" - ] - }, - { - "type": "object", - "properties": { - "nodeLL3": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL3" - ] - }, - { - "type": "object", - "properties": { - "nodeLL4": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL4" - ] - }, - { - "type": "object", - "properties": { - "nodeLL5": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL5" - ] - }, + "NodeOffsetPointXY": { + "oneOf": [ + { + "type": "object", + "properties": { + "nodeXY1": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY1" + ] + }, + { + "type": "object", + "properties": { + "nodeXY2": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY2" + ] + }, + { + "type": "object", + "properties": { + "nodeXY3": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY3" + ] + }, + { + "type": "object", + "properties": { + "nodeXY4": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY4" + ] + }, + { + "type": "object", + "properties": { + "nodeXY5": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY5" + ] + }, + { + "type": "object", + "properties": { + "nodeXY6": { + "$ref": "#/$defs/NodeXYPoint" + } + }, + "required": [ + "nodeXY6" + ] + }, + { + "type": "object", + "properties": { + "nodeLatLon": { + "$ref": "#/$defs/NodeLLmD" + } + }, + "required": [ + "nodeLatLon" + ] + } + ] + }, + "NodeAttributeSet": { + "type": "object", + "properties": { + "localNode": { + "type": "array", + "prefixItems": [ { - "type": "object", - "properties": { - "nodeLL6": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLL6" - ] - }, + "$ref": "#/$defs/NodeAttributeXY" + } + ] + }, + "disabled": { + "type": "array", + "prefixItems": [ { - "type": "object", - "properties": { - "nodeLatLon": { - "$ref": "#/$defs/J2735NodeLLDelta" - } - }, - "required": [ - "nodeLatLon" - ] + "$ref": "#/$defs/SegmentAttributeXY" } ] + }, + "enabled": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/SegmentAttributeXY" + } + ] + }, + "data": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/LaneDataAttribute" + } + ] + }, + "dWidth": { + "type": "number" + }, + "dElevation": { + "type": "number" } - }, - "required": [ - "delta" + } + }, + "NodeAttributeXY": { + "enum": [ + "reserved", + "stopLine", + "roundedCapStyleA", + "roundedCapStyleB", + "mergePoint", + "divergePoint", + "downstreamStopLine", + "downstreamStartNode", + "closedToTraffic", + "safeIsland", + "curbPresentAtStepOff", + "hydrantPresent" + ] + }, + "SegmentAttributeXY": { + "enum": [ + "reserved", + "doNotBlock", + "whiteLine", + "mergingLaneLeft", + "mergingLaneRight", + "curbOnLeft", + "curbOnRight", + "loadingzoneOnLeft", + "loadingzoneOnRight", + "turnOutPointOnLeft", + "turnOutPointOnRight", + "adjacentParkingOnLeft", + "adjacentParkingOnRight", + "adjacentBikeLaneOnLeft", + "adjacentBikeLaneOnRight", + "sharedBikeLane", + "bikeBoxInFront", + "transitStopOnLeft", + "transitStopOnRight", + "transitStopInLane", + "sharedWithTrackedVehicle", + "safeIsland", + "lowCurbsPresent", + "rumbleStripPresent", + "audibleSignalingPresent", + "adaptiveTimingPresent", + "rfSignalRequestPresent", + "partialCurbIntrusion", + "taperToLeft", + "taperToRight", + "taperToCenterLine", + "parallelParking", + "headInParking", + "freeParking", + "timeRestrictionsOnParking", + "costToPark", + "midBlockCurbPresent", + "unEvenPavementPresent" ] }, - "J2735NodeXYDelta": { + "LaneDataAttribute": { "type": "object", "properties": { - "x": { + "pathEndPointAngle": { "type": "number" }, - "y": { + "laneCrownPointCenter": { "type": "number" + }, + "laneCrownPointLeft": { + "type": "number" + }, + "laneCrownPointRight": { + "type": "number" + }, + "laneAngle": { + "type": "number" + }, + "speedLimits": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/RegulatorySpeedLimit" + } + ] } }, "required": [ - "x", - "y" + "pathEndPointAngle", + "laneCrownPointCenter", + "laneCrownPointLeft", + "laneCrownPointRight", + "laneAngle", + "speedLimits" ] }, - "J2735NodeLLDelta": { + "RegulatorySpeedLimit": { "type": "object", "properties": { - "lat": { - "type": "number" + "type": { + "enum": [ + "unknown", + "maxSpeedInSchoolZone", + "maxSpeedInSchoolZoneWhenChildrenArePresent", + "maxSpeedInConstructionZone", + "vehicleMinSpeed", + "vehicleMaxSpeed", + "vehicleNightMaxSpeed", + "truckMinSpeed", + "truckMaxSpeed", + "truckNightMaxSpeed", + "vehiclesWithTrailersMinSpeed", + "vehiclesWithTrailersMaxSpeed", + "vehiclesWithTrailersNightMaxSpeed" + ] }, - "lon": { + "speed": { "type": "number" } }, "required": [ - "lon", - "lat" + "type", + "speed" ] }, - "J2735GeometricProjection": { + "NodeLL": { "type": "object", "properties": { - "direction": { - "type": "string" - }, - "extent": { - "type": "string" + "delta": { + "$ref": "#/$defs/NodeOffsetPointLL" }, - "laneWidth": { - "type": "string" + "attributes": { + "$ref": "#/$defs/NodeAttributeSet" + } + }, + "required": [ + "delta" + ] + }, + "NodeOffsetPointLL": { + "oneOf": [ + { + "type": "object", + "properties": { + "nodeLL1": { + "$ref": "#/$defs/NodeLLmD" + } + }, + "required": [ + "nodeLL1" + ] }, - "circle": { + { "type": "object", "properties": { - "center": { - "$ref": "#/$defs/J2735Position3D" - }, - "radius": { - "type": "string" - }, - "units": { - "$ref": "#/$defs/J2735DistanceUnits" + "nodeLL2": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "center", - "radius", - "units" + "nodeLL2" ] - } - }, - "required": [ - "direction", - "circle" - ] - }, - "J2735DF_Content": { - "oneOf": [ + }, { "type": "object", "properties": { - "advisory": { - "$ref": "#/$defs/J2735DF_ContentSequence" + "nodeLL3": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "advisory" + "nodeLL3" ] }, { "type": "object", "properties": { - "workZone": { - "$ref": "#/$defs/J2735DF_ContentSequence" + "nodeLL4": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "workZone" + "nodeLL4" ] }, { "type": "object", "properties": { - "genericSign": { - "$ref": "#/$defs/J2735DF_ContentSequence" + "nodeLL5": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "genericSign" + "nodeLL5" ] }, { "type": "object", "properties": { - "speedLimit": { - "$ref": "#/$defs/J2735DF_ContentSequence" + "nodeLL6": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "speedLimit" + "nodeLL6" ] }, { "type": "object", "properties": { - "exitService": { - "$ref": "#/$defs/J2735DF_ContentSequence" + "nodeLatLon": { + "$ref": "#/$defs/NodeLLmD" } }, "required": [ - "exitService" + "nodeLatLon" ] } ] }, - "J2735DF_ContentSequence": { + "NodeXYPoint": { + "type": "object", + "properties": { + "x": { + "type": "number" + }, + "y": { + "type": "number" + } + }, + "required": [ + "x", + "y" + ] + }, + "NodeLLmD": { + "type": "object", + "properties": { + "lat": { + "type": "number" + }, + "lon": { + "type": "number" + } + }, + "required": [ + "lon", + "lat" + ] + }, + "ComputedLane": { + "type": "object", + "properties": { + "referenceLaneId": { + "type": "number" + }, + "offsetXaxis": { + "$ref": "#/$defs/OffsetXaxisChoice" + }, + "offsetYaxis": { + "$ref": "#/$defs/OffsetYaxisChoice" + }, + "rotateXY": { + "type": "number" + }, + "scaleXaxis": { + "type": "number" + }, + "scaleYaxis": { + "type": "number" + } + }, + "required": [ + "referenceLaneId", + "offsetXaxis", + "offsetYaxis" + ] + }, + "OffsetXaxisChoice": { "oneOf": [ { "type": "object", "properties": { - "SEQUENCE": { - "type": "array", - "prefixItems": [ - { - "$ref": "#/$defs/J2735DF_ContentSequenceItem" - } - ] + "small": { + "type": "number" } }, "required": [ - "SEQUENCE" + "small" ] }, { "type": "object", "properties": { - "SEQUENCE": { - "$ref": "#/$defs/J2735DF_ContentSequenceItem" + "large": { + "type": "number" } }, "required": [ - "SEQUENCE" + "large" ] } ] }, - "J2735DF_ContentSequenceItem": { - "type": "object", - "properties": { - "item": { + "OffsetYaxisChoice": { + "oneOf": [ + { "type": "object", "properties": { - "itis": { - "type": "string" + "small": { + "type": "number" } }, "required": [ - "itis" + "small" + ] + }, + { + "type": "object", + "properties": { + "large": { + "type": "number" + } + }, + "required": [ + "large" ] } - }, - "required": [ - "item" ] }, - "J2735Position3D": { + "GeometricProjection": { "type": "object", "properties": { - "lat": { - "type": "string" + "direction": { + "$ref": "#/$defs/HeadingSlice" }, - "long": { - "type": "string" + "extent": { + "$ref": "#/$defs/Extent" }, - "elevation": { - "type": [ - "string", - "null" - ] + "laneWidth": { + "type": "number" + }, + "circle": { + "$ref": "#/$defs/Circle" } }, "required": [ - "lat", - "long" + "direction", + "circle" ] }, - "OdePosition3D": { + "Circle": { "type": "object", "properties": { - "latitude": { - "type": "number" + "center": { + "$ref": "#/$defs/Position3D" }, - "longitude": { + "radius": { "type": "number" }, - "elevation": { - "type": "number" + "units": { + "$ref": "#/$defs/DistanceUnits" } }, "required": [ - "latitude", - "longitude" + "center", + "radius", + "units" ] }, - "J2735RoadSegmentReferenceID": { + "ValidRegion": { "type": "object", "properties": { - "id": { - "type": "number" + "direction": { + "$ref": "#/$defs/HeadingSlice" }, - "region": { - "type": "number" + "extent": { + "$ref": "#/$defs/Extent" + }, + "area": { + "$ref": "#/$defs/AreaChoice" } }, "required": [ - "id" + "direction", + "extent", + "area" ] }, - "J2735DistanceUnits": { + "Extent": { + "enum": [ + "useInstantlyOnly", + "useFor3meters", + "useFor10meters", + "useFor50meters", + "useFor100meters", + "useFor500meters", + "useFor1000meters", + "useFor5000meters", + "useFor10000meters", + "useFor50000meters", + "useFor100000meters", + "useFor500000meters", + "useFor1000000meters", + "useFor5000000meters", + "useFor10000000meters", + "forever" + ] + }, + "AreaChoice": { "oneOf": [ { "type": "object", "properties": { - "centimeter": { - "type": "string" + "shapePointSet": { + "$ref": "#/$defs/ShapePointSet" } }, "required": [ - "centimeter" + "shapePointSet" ] }, { "type": "object", "properties": { - "cm2-5": { - "type": "string" + "circle": { + "$ref": "#/$defs/Circle" } }, "required": [ - "cm2-5" + "circle" ] }, { "type": "object", "properties": { - "decimeter": { - "type": "string" + "regionPointSet": { + "$ref": "#/$defs/RegionPointSet" } }, "required": [ - "decimeter" + "regionPointSet" ] + } + ] + }, + "ShapePointSet": { + "type": "object", + "properties": { + "anchor": { + "$ref": "#/$defs/Position3D" + }, + "laneWidth": { + "type": "number" + }, + "directionality": { + "$ref": "#/$defs/DirectionOfUse" }, + "nodeList": { + "$ref": "#/$defs/NodeListXY" + } + }, + "required": [ + "nodeList" + ] + }, + "RegionPointSet": { + "type": "object", + "properties": { + "anchor": { + "$ref": "#/$defs/Position3D" + }, + "scale": { + "type": "number" + }, + "nodeList": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/RegionList" + } + ] + } + }, + "required": [ + "nodeList" + ] + }, + "RegionList": { + "type": "object", + "properties": { + "xOffset": { + "type": "number" + }, + "yOffset": { + "type": "number" + }, + "zOffset": { + "type": "number" + } + }, + "required": [ + "xOffset", + "yOffset" + ] + }, + "ContentChoice": { + "oneOf": [ { "type": "object", "properties": { - "meter": { - "type": "string" + "advisory": { + "$ref": "#/$defs/ContentSequence" } }, "required": [ - "meter" + "advisory" ] }, { "type": "object", "properties": { - "kilometer": { - "type": "string" + "workZone": { + "$ref": "#/$defs/ContentSequence" } }, "required": [ - "kilometer" + "workZone" ] }, { "type": "object", "properties": { - "foot": { - "type": "string" + "genericSign": { + "$ref": "#/$defs/ContentSequence" } }, "required": [ - "foot" + "genericSign" ] }, { "type": "object", "properties": { - "yard": { - "type": "string" + "speedLimit": { + "$ref": "#/$defs/ContentSequence" } }, "required": [ - "yard" + "speedLimit" ] }, { "type": "object", "properties": { - "mile": { - "type": "string" + "exitService": { + "$ref": "#/$defs/ContentSequence" } }, "required": [ - "mile" + "exitService" ] } ] + }, + "ContentSequence": { + "type": "array", + "prefixItems": [ + { + "$ref": "#/$defs/ContentSequenceItem" + } + ] + }, + "ContentSequenceItem": { + "type": "object", + "properties": { + "item": { + "type": "object", + "properties": { + "itis": { + "type": ["string", "number"] + } + }, + "required": [ + "itis" + ] + } + }, + "required": [ + "item" + ] + + }, + "Position3D": { + "type": "object", + "properties": { + "lat": { + "type": "number" + }, + "long": { + "type": "number" + }, + "elevation": { + "type": "number" + } + }, + "required": [ + "lat", + "long" + ] + }, + "RoadSegmentReferenceID": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "region": { + "type": "number" + } + }, + "required": [ + "id" + ] + }, + "DistanceUnits": { + "enum": [ + "centimeter", + "cm2-5", + "decimeter", + "meter", + "kilometer", + "foot", + "yard", + "mile" + ] } } } \ No newline at end of file diff --git a/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json index 8d38a5a14..3e096b913 100644 --- a/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json +++ b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"89b9de68-7e91-4491-886f-d95276b67907","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-11-26T07:29:12.257Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F80AE70165E87AD5DB73EE53601D49C0F775D9B0B01C266509C496663068FFFF93F43448C001EA007F95937EAD35AC9A5FA54EADF62C17316CB99385CDA00000000266509C4966630689388C200021000EBE86F264E051097630004008027BBAECD8C070999427125998C1A3FFFE4FD0D1230007A801FE564DFAB4D6B2697E953AB7D8B05CC5B2E64E1736800000000999427125998C1A24E230800084003AFA1BC993814425D8C0000003023DDD766C0913189880FB96879A18B9BEE7183450F963D09BEACCD8A5B06FB639381F59F27808066C418702727350EEAB14E752EA27C0AF0540260F9187757E2192FECE54EF4F0032D653EFB5938AE340F6D3122636E7F61F9BD3A1CB5B4695B634BFFADD4018543C5862B4D608430EA9F2FCE99599935425B5DD64F77EC1495571FB50D0B03FF442529D80EA12704C08088E30204E84B3BD03B6001002009EEEBB360A4000801004F775D9B00C1265E25E2A8F3809BC14F804485CC84244966B611857569128444CB48453B9DC84ACCB06E225C6B7C36122F9B9E008F85DC55C42092CD4611CE5A3B107BFB25F0864A19C5049086E7A024071790208BE4FAF8D63F87FC1027B83FF235FF8DFFC6116EAC028093B920DF0468311194237188767113D84037081D31FE2C6B3443FED434C4F1FF3311F183E46892F5DE8D049958EF3E21B27675C100","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735Tim","data":{"msgCnt":"1","timeStamp":"417415","packetID":"AD5DB73EE53601D49C","dataFrames":[{"notUsed":"0","frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":38.8311689,"longitude":-104.8408366},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startYear":"2024","startTime":"428312","durationTime":"30","priority":"5","notUsed1":"0","regions":[{"name":"I_US-24_RSU_10.16.28.6","id":{"region":0,"id":0},"anchor":{"latitude":38.8311689,"longitude":-104.8408366},"laneWidth":5000,"directionality":"both","closedPath":false,"description":{"path":{"scale":0,"offset":{"ll":{"nodes":[{"delta":{"nodeLL1":{"lon":1726,"lat":111}}},{"delta":{"nodeLL5":{"lon":1208360,"lat":77510}}}]}}}}}],"notUsed2":"0","notUsed3":"0","content":{"workZone":{"SEQUENCE":[{"item":{"itis":"1025"}}]}}},{"notUsed":"0","frameType":"advisory","msgId":{"roadSignID":{"position":{"latitude":38.8311689,"longitude":-104.8408366},"viewAngle":"1111111111111111","mutcdCode":"warning"}},"startYear":"2024","startTime":"428312","durationTime":"30","priority":"5","notUsed1":"0","regions":[{"name":"I_US-24_RSU_10.16.28.6","id":{"region":0,"id":0},"anchor":{"latitude":38.8311689,"longitude":-104.8408366},"laneWidth":5000,"directionality":"both","closedPath":false,"description":{"path":{"scale":0,"offset":{"ll":{"nodes":[{"delta":{"nodeLL1":{"lon":1726,"lat":111}}},{"delta":{"nodeLL5":{"lon":1208360,"lat":77510}}}]}}}}}],"notUsed2":"0","notUsed3":"0","content":{"advisory":{"SEQUENCE":[{"item":{"itis":"770"}}]}}}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java index 6fe034246..b109ee671 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java @@ -23,7 +23,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; /* - * EDITED -> notUsed, notUsed1, notUsed2, notUsed3 fields. + * EDITED -> notUsed, notUsed1, notUsed2, notUsed3, durationTime fields. */ /** @@ -71,7 +71,7 @@ public class TravelerDataFrame extends Asn1Sequence { private MinuteOfTheYear startTime; @Asn1Property(tag = 5) @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) - private MinutesDuration duratonTime; + private MinutesDuration durationTime; @Asn1Property(tag = 6) @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) private SignPrority priority; diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java index a9c3118a9..b1a45becb 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/builders/MAPBuilderTest.java @@ -46,21 +46,7 @@ public void shouldTranslateMap() { } J2735MAP actualMap = MAPBuilder.genericMAP(jsonMap.findValue("MapData")); String expected = """ - {\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\": - {\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\": - {\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[ - {\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false, - \"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicl - eTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false, - \"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false, - \"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false, - \"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\": - {\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\": - false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\": - false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\": - {\"nodes\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\": - {\"x\":43,\"y\":24}}}]}}]}}]}} - """; + {\"msgIssueRevision\":4,\"layerType\":\"mixedContent\",\"layerID\":12,\"intersections\":{\"intersectionGeometry\":[{\"id\":{\"id\":156},\"revision\":1,\"refPoint\":{\"latitude\":38.9284111,\"longitude\":-77.2410713},\"laneSet\":{\"GenericLane\":[{\"laneID\":1,\"laneAttributes\":{\"directionalUse\":{\"ingressPath\":false,\"egressPath\":false},\"shareWith\":{\"busVehicleTraffic\":false,\"trackedVehicleTraffic\":false,\"individualMotorizedVehicleTraffic\":false,\"taxiVehicleTraffic\":false,\"overlappingLaneDescriptionProvided\":false,\"cyclistVehicleTraffic\":false,\"otherNonMotorizedTrafficTypes\":false,\"multipleLanesTreatedAsOneLane\":false,\"pedestrianTraffic\":false,\"pedestriansTraffic\":false},\"laneType\":{\"vehicle\":{\"isVehicleRevocableLane\":false,\"isVehicleFlyOverLane\":false,\"permissionOnRequest\":false,\"hasIRbeaconCoverage\":false,\"restrictedToBusUse\":false,\"restrictedToTaxiUse\":false,\"restrictedFromPublicUse\":false,\"hovLaneUseOnly\":false}}},\"nodeList\":{\"nodes\":[{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}},{\"delta\":{\"nodeXY2\":{\"x\":43,\"y\":24}}}]}}]}}]}}"""; assertEquals(expected, actualMap.toJson()); } } diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java index 8da6c48bd..eb4a1a966 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceTest.java @@ -35,10 +35,5 @@ public void testSerializeJson() throws JsonProcessingException { } private static final String EXPECTED_JSON = """ - {"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true, - "from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true, - "from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true, - "from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true, - "from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true, - "from337-5to360-0degrees":true}"""; + {"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true,"from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true,"from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true,"from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true,"from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true,"from337-5to360-0degrees":true}"""; } diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json index 0f7dd9c1f..3e096b913 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"adb022ef-9a97-4aa3-8bab-1fde55b620a1","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-05T10:21:33.228Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml index 072580466..a7b211480 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml @@ -1,3 +1,4 @@ + @@ -13,13 +14,13 @@ us.dot.its.jpo.ode.model.OdeAsn1Payload - adb022ef-9a97-4aa3-8bab-1fde55b620a1 + 8af76b08-89bf-422e-b674-0f0ee065666f 1 0 0 0 - 2024-12-05T10:21:33.228Z + 2024-12-06T10:39:42.806Z 7 0 From dc0e975f6184ebda5a2ec5eadbd826f199365bf8 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Fri, 6 Dec 2024 10:00:19 -0700 Subject: [PATCH 143/264] Addressed checkstyle warnings for InetPacketSender, TimDepositController, TimDepositControllerTest, TimTransmogrifierTest & OdeTravelerInformationMessage --- .../its/jpo/ode/inet/InetPacketSender.java | 101 +++++------ .../j2735/OdeTravelerInformationMessage.java | 168 +++++++++++++----- .../ode/traveler/TimDepositController.java | 16 +- .../traveler/TimDepositControllerTest.java | 24 ++- .../ode/traveler/TimTransmogrifierTest.java | 13 +- 5 files changed, 196 insertions(+), 126 deletions(-) diff --git a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java index 333d30ee2..5ac17ac1c 100644 --- a/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java +++ b/jpo-ode-common/src/main/java/us/dot/its/jpo/ode/inet/InetPacketSender.java @@ -1,17 +1,17 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.inet; @@ -20,12 +20,11 @@ import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; - import lombok.extern.slf4j.Slf4j; /** * Sender/Forwarder helper class for use by Forwarder, Transport, and Data Sink - * that need to send packets around + * that need to send packets around. */ @Slf4j public class InetPacketSender { @@ -34,7 +33,7 @@ public class InetPacketSender { "Invalid Parameters. Parameters destination point and payload can not be null"; /** - * Inet address and port to forward packets to + * Inet address and port to forward packets to. */ private InetPoint frwdPoint; @@ -61,38 +60,18 @@ public InetPacketSender(InetPoint frwdPoint) { * Forward packet. Intended client is the forwarder that received a packet * * @param packet UDP packet - * @throws InetPacketException + * @throws InetPacketException if the packet is null or the destination is not defined */ public void forward(DatagramPacket packet) throws InetPacketException { if (packet == null) { log.warn("Ignoring forward request for null packet"); return; } - if (frwdPoint == null) { - throw new InetPacketException( - "Couldn't forward packet. Reason: Forwarding destination is not defined."); - } - send(frwdPoint, new InetPacket(packet).getBundle()); - } - - /** - * Send packet. Intended client is the forwarder that sends outbound packet - * - * @param packet outbound packet that contains destination+payload bundle - * @throws InetPacketException - */ - public void send(DatagramPacket packet) throws InetPacketException { - if (packet == null) { - log.warn("Ignoring send request for null packet"); - return; + if (frwdPoint == null) { + throw new InetPacketException( + "Couldn't forward packet. Reason: Forwarding destination is not defined."); } - InetPacket p = new InetPacket(packet); - InetPoint point = p.getPoint(); - if (point == null) { - throw new InetPacketException( - "Couldn't send packet. Reason: Destination is not defined in the packet (not a bundle?)"); - } - send(point, p.getPayload()); + send(frwdPoint, new InetPacket(packet).getBundle()); } /** @@ -101,15 +80,15 @@ public void send(DatagramPacket packet) throws InetPacketException { * * @param dstPoint destination address and port for forwarder to forward to * @param payload data to forward - * @throws InetPacketException + * @throws InetPacketException if the packet is null or the destination is not defined */ public void forward(InetPoint dstPoint, byte[] payload) throws InetPacketException { - if (dstPoint == null || payload == null) { - throw new InetPacketException(INVALID_PARAMETERS_MSG); - } - if (frwdPoint == null) { - log.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); - } + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } + if (frwdPoint == null) { + log.warn("Couldn't forward packet. Reason: Forwarding destination is not defined."); + } if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll())) { send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); } else { @@ -125,13 +104,13 @@ public void forward(InetPoint dstPoint, byte[] payload) throws InetPacketExcepti * @param dstPoint destination address and port of the final destination * @param payload data to forward or send * @param fromForwarder whether the original request came through a forwarder - * @throws InetPacketException + * @throws InetPacketException if the packet is null or the destination is not defined */ public void forward(InetPoint dstPoint, byte[] payload, boolean fromForwarder) throws InetPacketException { - if (dstPoint == null || payload == null) { - throw new InetPacketException(INVALID_PARAMETERS_MSG); - } + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } if (frwdPoint != null && (dstPoint.isIPv6Address() || isForwardAll() || fromForwarder)) { send(frwdPoint, new InetPacket(dstPoint, payload).getBundle()); } else { @@ -140,18 +119,38 @@ public void forward(InetPoint dstPoint, byte[] payload, boolean fromForwarder) } } + /** + * Send packet. Intended client is the forwarder that sends outbound packet + * + * @param packet outbound packet that contains destination+payload bundle + * @throws InetPacketException if the packet is null or the destination is not defined + */ + public void send(DatagramPacket packet) throws InetPacketException { + if (packet == null) { + log.warn("Ignoring send request for null packet"); + return; + } + InetPacket p = new InetPacket(packet); + InetPoint point = p.getPoint(); + if (point == null) { + throw new InetPacketException( + "Couldn't send packet. Reason: Destination is not defined in the packet (not a bundle?)"); + } + send(point, p.getPayload()); + } + /** * Send payload to the destination specified. Intended clients are Transport or * Data Sink sending directly to the client * * @param dstPoint destination address and port to send to * @param payload data to send - * @throws InetPacketException + * @throws InetPacketException if the packet is null or the destination is not defined */ public void send(InetPoint dstPoint, byte[] payload) throws InetPacketException { - if (dstPoint == null || payload == null) { - throw new InetPacketException(INVALID_PARAMETERS_MSG); - } + if (dstPoint == null || payload == null) { + throw new InetPacketException(INVALID_PARAMETERS_MSG); + } try (DatagramSocket sock = new DatagramSocket()) { DatagramPacket packet = new DatagramPacket(payload, payload.length, dstPoint.getInetAddress(), dstPoint.port); @@ -164,7 +163,7 @@ public void send(InetPoint dstPoint, byte[] payload) throws InetPacketException } /** - * Reports whether outbound IPv4 messages should be send directly or forwarded. + * Reports whether outbound IPv4 messages should be sent directly or forwarded. * * @return true if IPv4 packets are forwarded in addition to IPv6 packets */ @@ -173,6 +172,8 @@ public boolean isForwardAll() { } /** + * Sets whether outbound IPv4 messages should be sent directly or forwarded. + * * @param forwardAll Directs how to handle IPv4 messages. * Specify true to force forwarding IPv4 messages, and false * to always send them directly. diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java index 98607ef71..b85747ac2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/OdeTravelerInformationMessage.java @@ -1,22 +1,23 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.plugin.j2735; import com.fasterxml.jackson.annotation.JsonAlias; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.JsonNode; import java.math.BigDecimal; import lombok.EqualsAndHashCode; @@ -31,6 +32,9 @@ import us.dot.its.jpo.ode.plugin.j2735.timstorage.FrameType; import us.dot.its.jpo.ode.plugin.j2735.timstorage.MutcdCode; +/** + * OdeTravelerInformationMessage. + */ @EqualsAndHashCode(callSuper = false) public class OdeTravelerInformationMessage extends OdeObject { @@ -91,6 +95,9 @@ public void setAsnDataFrames(JsonNode stringDataFrames) { this.asnDataFrames = stringDataFrames; } + /** + * NodeListXY. + */ public static class NodeListXY extends OdeObject { private static final long serialVersionUID = 1L; private ComputedLane computedLane; @@ -113,6 +120,9 @@ public void setNodexy(NodeXY[] nodexy) { } } + /** + * Area. + */ @EqualsAndHashCode(callSuper = false) public static class Area extends OdeObject { private static final long serialVersionUID = 1L; @@ -146,6 +156,9 @@ public void setRegionPoint(RegionPointSet regionPoint) { } } + /** + * ComputedLane. + */ @EqualsAndHashCode(callSuper = false) public static class ComputedLane extends OdeObject { @@ -206,6 +219,9 @@ public void setScaleYaxis(BigDecimal scaleYaxis) { } } + /** + * NodeXY. + */ @EqualsAndHashCode(callSuper = false) public static class NodeXY extends OdeObject { @@ -213,8 +229,10 @@ public static class NodeXY extends OdeObject { private String delta; private BigDecimal nodeLat; private BigDecimal nodeLong; - private BigDecimal x; - private BigDecimal y; + @JsonProperty("x") + private BigDecimal xpos; + @JsonProperty("y") + private BigDecimal ypos; private Attributes attributes; public String getDelta() { @@ -241,20 +259,20 @@ public void setNodeLong(BigDecimal nodeLong) { this.nodeLong = nodeLong; } - public BigDecimal getX() { - return x; + public BigDecimal getXpos() { + return xpos; } - public void setX(BigDecimal x) { - this.x = x; + public void setXpos(BigDecimal xpos) { + this.xpos = xpos; } - public BigDecimal getY() { - return y; + public BigDecimal getYpos() { + return ypos; } - public void setY(BigDecimal y) { - this.y = y; + public void setYpos(BigDecimal ypos) { + this.ypos = ypos; } public Attributes getAttributes() { @@ -266,6 +284,9 @@ public void setAttributes(Attributes attributes) { } } + /** + * LocalNode. + */ @EqualsAndHashCode(callSuper = false) public static class LocalNode extends OdeObject { @@ -281,6 +302,9 @@ public void setType(long type) { } } + /** + * DisabledList. + */ @EqualsAndHashCode(callSuper = false) public static class DisabledList extends OdeObject { @@ -296,6 +320,9 @@ public void setType(long type) { } } + /** + * EnabledList. + */ @EqualsAndHashCode(callSuper = false) public static class EnabledList extends OdeObject { @@ -311,6 +338,9 @@ public void setType(long type) { } } + /** + * SpeedLimits. + */ @EqualsAndHashCode(callSuper = false) public static class SpeedLimits extends OdeObject { @@ -335,6 +365,9 @@ public void setVelocity(BigDecimal velocity) { } } + /** + * DataList. + */ @EqualsAndHashCode(callSuper = false) public static class DataList extends OdeObject { @@ -395,6 +428,9 @@ public void setSpeedLimits(SpeedLimits[] speedLimits) { } } + /** + * Attributes. + */ @EqualsAndHashCode(callSuper = false) public static class Attributes extends OdeObject { @@ -403,8 +439,10 @@ public static class Attributes extends OdeObject { private DisabledList[] disabledLists; private EnabledList[] enabledLists; private DataList[] dataLists; - private BigDecimal dWidth; - private BigDecimal dElevation; + @JsonProperty("dWidth") + private BigDecimal dwidth; + @JsonProperty("dElevation") + private BigDecimal delevation; public LocalNode[] getLocalNodes() { return localNodes; @@ -438,46 +476,52 @@ public void setDataLists(DataList[] dataLists) { this.dataLists = dataLists; } - public BigDecimal getdWidth() { - return dWidth; + public BigDecimal getDwidth() { + return dwidth; } - public void setdWidth(BigDecimal dWidth) { - this.dWidth = dWidth; + public void setDwidth(BigDecimal dwidth) { + this.dwidth = dwidth; } - public BigDecimal getdElevation() { - return dElevation; + public BigDecimal getDelevation() { + return delevation; } - public void setdElevation(BigDecimal dElevation) { - this.dElevation = dElevation; + public void setDelevation(BigDecimal delevation) { + this.delevation = delevation; } } + /** + * DataFrame. + */ @EqualsAndHashCode(callSuper = false) public static class DataFrame extends OdeObject { private static final long serialVersionUID = 537503046055742396L; @JsonAlias({"sspTimRights", "notUsed"}) - private short doNotUse1;// Start Header Information + private short doNotUse1; // Start Header Information private FrameType.TravelerInfoType frameType; private MsgId msgId; private String startDateTime; @JsonAlias("duratonTime") private int durationTime; - private int priority;// End header Information + private int priority; // End header Information @JsonAlias({"sspLocationRights", "notUsed1"}) - private short doNotUse2;// Start Region Information + private short doNotUse2; // Start Region Information private Region[] regions; @JsonAlias({"sspMsgContent", "sspMsgRights1", "notUsed2"}) - private short doNotUse3;// Start content Information + private short doNotUse3; // Start content Information @JsonAlias({"sspMsgTypes", "sspMsgRights2", "notUsed3"}) private short doNotUse4; private String content; private String[] items; - private String url;// End content Information + private String url; // End content Information + /** + * Region. + */ @EqualsAndHashCode(callSuper = false) public static class Region extends OdeObject { @@ -495,6 +539,9 @@ public static class Region extends OdeObject { private Geometry geometry; private OldRegion oldRegion; + /** + * OldRegion. + */ @EqualsAndHashCode(callSuper = false) public static class OldRegion extends OdeObject { @@ -503,6 +550,9 @@ public static class OldRegion extends OdeObject { private String extent; private Area area; + /** + * ShapePointSet. + */ @EqualsAndHashCode(callSuper = false) public static class ShapePointSet extends OdeObject { @@ -549,6 +599,9 @@ public void setNodeList(NodeListXY nodeList) { } } + /** + * RegionPointSet. + */ @EqualsAndHashCode(callSuper = false) public static class RegionPointSet extends OdeObject { @@ -557,36 +610,42 @@ public static class RegionPointSet extends OdeObject { private int scale; private RegionList[] regionList; + /** + * RegionList. + */ @EqualsAndHashCode(callSuper = false) public static class RegionList extends OdeObject { private static final long serialVersionUID = -5307620155601900634L; - private BigDecimal xOffset; - private BigDecimal yOffset; - private BigDecimal zOffset; - - public BigDecimal getzOffset() { - return zOffset; + @JsonProperty("xOffset") + private BigDecimal offsetX; + @JsonProperty("yOffset") + private BigDecimal offsetY; + @JsonProperty("zOffset") + private BigDecimal offsetZ; + + public BigDecimal getOffsetZ() { + return offsetZ; } - public void setzOffset(BigDecimal zOffset) { - this.zOffset = zOffset; + public void setOffsetZ(BigDecimal offsetZ) { + this.offsetZ = offsetZ; } - public BigDecimal getyOffset() { - return yOffset; + public BigDecimal getOffsetY() { + return offsetY; } - public void setyOffset(BigDecimal yOffset) { - this.yOffset = yOffset; + public void setOffsetY(BigDecimal offsetY) { + this.offsetY = offsetY; } - public BigDecimal getxOffset() { - return xOffset; + public BigDecimal getOffsetX() { + return offsetX; } - public void setxOffset(BigDecimal xOffset) { - this.xOffset = xOffset; + public void setOffsetX(BigDecimal offsetX) { + this.offsetX = offsetX; } } @@ -644,6 +703,9 @@ public void setDirection(String direction) { } } + /** + * Geometry. + */ public static class Geometry extends OdeObject { private static final long serialVersionUID = -7664796173893464468L; @@ -685,6 +747,9 @@ public void setDirection(String direction) { } } + /** + * Circle. + */ @EqualsAndHashCode(callSuper = false) public static class Circle extends OdeObject { @@ -731,6 +796,9 @@ public void setCenter(OdePosition3D center) { } } + /** + * Path. + */ @EqualsAndHashCode(callSuper = false) public static class Path extends OdeObject { @@ -871,6 +939,9 @@ public void setName(String name) { } + /** + * RoadSignID. + */ @EqualsAndHashCode(callSuper = false) public static class RoadSignID extends OdeObject { @@ -914,6 +985,9 @@ public void setCrc(String crc) { } } + /** + * MsgId. + */ @EqualsAndHashCode(callSuper = false) public static class MsgId extends Asn1Object { private static final long serialVersionUID = 1L; diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index fe4af05ce..aab72bea1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -101,12 +101,12 @@ public TimDepositControllerException(String errMsg) { /** * Constructor. - - * @param odeKafkaProperties odeKafkaProperties - * @param asn1CoderTopics asn1CoderTopics - * @param pojoTopics pojoTopics - * @param jsonTopics jsonTopics - * @param ingestTrackerProperties ingestTrackerProperties + * + * @param odeKafkaProperties odeKafkaProperties + * @param asn1CoderTopics asn1CoderTopics + * @param pojoTopics pojoTopics + * @param jsonTopics jsonTopics + * @param ingestTrackerProperties ingestTrackerProperties * @param securityServicesProperties securityServicesProperties */ @Autowired @@ -154,7 +154,7 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST. * * @param jsonString TIM in JSON - * @param verb ODE.PUT or ODE.POST + * @param verb ODE.PUT or ODE.POST * @return list of success/failures */ public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { @@ -261,7 +261,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request if ((request.getRsus() == null || request.getSnmp() == null) && request.getSdw() == null) { String warningMsg = "Warning: TIM contains no RSU, SNMP, or SDW fields." - + " Message only published to broadcast streams."; + + " Message only published to broadcast streams."; log.warn(warningMsg); return ResponseEntity.status(HttpStatus.OK).body(JsonUtils.jsonKeyValue(WARNING, warningMsg)); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index cf6027fca..65df49b9e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -100,25 +100,24 @@ public void missingRequestElementShouldReturnMissingRequestError() { @Test public void invalidTimestampShouldReturnInvalidTimestampError() { - ResponseEntity actualResponse = testTimDepositController - .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"201-03-13T01:07:11-05:00\"}}"); + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{},\"tim\":{\"timeStamp\":\"201-03-13T01:07:11-05:00\"}}"); assertEquals("{\"error\":\"Invalid timestamp in tim record: 201-03-13T01:07:11-05:00\"}", actualResponse.getBody()); } @Test public void messageWithNoRSUsOrSDWShouldReturnWarning() { - ResponseEntity actualResponse = testTimDepositController - .postTim("{\"request\":{},\"tim\":{\"timeStamp\":\"2018-03-13T01:07:11-05:00\"}}"); + ResponseEntity actualResponse = testTimDepositController.postTim( + "{\"request\":{},\"tim\":{\"timeStamp\":\"2018-03-13T01:07:11-05:00\"}}"); assertEquals( "{\"warning\":\"Warning: TIM contains no RSU, SNMP, or SDW fields. Message only published to broadcast streams.\"}", actualResponse.getBody()); } @Test - public void failedObjectNodeConversionShouldReturnConvertingError( - @Capturing - TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) + public void failedObjectNodeConversionShouldReturnConvertingError(@Capturing + TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) throws JsonUtilsException, TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { @@ -145,8 +144,7 @@ public void failedXmlConversionShouldReturnConversionError( new Expectations() { { TimTransmogrifier.convertToXml((DdsAdvisorySituationData) any, (ObjectNode) any, - (OdeMsgMetadata) any, - (SerialId) any); + (OdeMsgMetadata) any, (SerialId) any); result = new XmlUtilsException("testException123", null); } }; @@ -168,12 +166,10 @@ public void testSuccessfulMessageReturnsSuccessMessagePost( } @Test - public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() - throws Exception { + public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() throws Exception { String file = "/sdwRequest.json"; - String json = IOUtils.toString( - TimDepositControllerTest.class.getResourceAsStream(file), - "UTF-8"); + String json = + IOUtils.toString(TimDepositControllerTest.class.getResourceAsStream(file), "UTF-8"); ResponseEntity actualResponse = testTimDepositController.postTim(json); assertEquals("{\"success\":\"true\"}", actualResponse.getBody()); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 4c5560483..a97dd1ce0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -305,8 +305,8 @@ void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() // verify String expectedXml = new String(Files.readAllBytes(Paths.get( - "src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))) - .replaceAll("\\s", "") // remove all whitespace + "src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml"))).replaceAll( + "\\s", "") // remove all whitespace .replaceAll("", ""); // add space before closing tag Assertions.assertEquals(expectedXml, actualXML); } @@ -314,8 +314,8 @@ void testConvertToXML_VerifyPositionElementNotInCircleElementAfterConversion() @Test void testCreateOdeTimData() throws JsonUtilsException { - JSONObject testObject = JsonUtils - .toJSONObject("{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); + JSONObject testObject = JsonUtils.toJSONObject( + "{\"metadata\":{\"object\":\"value\"},\"payload\":{\"object\":\"value\"}}"); JSONObject actualOdeTimData = TimTransmogrifier.createOdeTimData(testObject); assertEquals( @@ -380,9 +380,8 @@ private OdeRequestMsgMetadata prepareMetadata(OdeTravelerInputData odeTID, Seria for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); latestStartDateTime = latestStartDateTime == null || - latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) - ? dateFormat.parse(dataFrameItem.getStartDateTime()) - : latestStartDateTime; + latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) ? + dateFormat.parse(dataFrameItem.getStartDateTime()) : latestStartDateTime; } timMetadata.setMaxDurationTime(maxDurationTime); timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); From 1851067a89429c98d6cdb7d64229566b3efbfb1c Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Fri, 6 Dec 2024 10:27:04 -0700 Subject: [PATCH 144/264] Addressed checkstyle warnings for TimDepositControllerTest & TimTransmogrifierTest Signed-off-by: dmccoystephenson --- .../traveler/TimDepositControllerTest.java | 57 +++++++++---------- .../ode/traveler/TimTransmogrifierTest.java | 51 ++++++++++------- 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index 65df49b9e..ee8a95769 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -1,38 +1,35 @@ /******************************************************************************* - * Copyright 2018 572682 + * Copyright 2018 572682. * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at + * of the License at

* - * http://www.apache.org/licenses/LICENSE-2.0 + *

http://www.apache.org/licenses/LICENSE-2.0

* - * Unless required by applicable law or agreed to in writing, software + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ package us.dot.its.jpo.ode.traveler; -import org.apache.commons.io.IOUtils; - import static org.junit.Assert.assertEquals; -import org.junit.jupiter.api.Test; -import org.springframework.http.ResponseEntity; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; - import mockit.Capturing; import mockit.Expectations; import mockit.Injectable; import mockit.Tested; +import org.apache.commons.io.IOUtils; +import org.junit.jupiter.api.Test; +import org.springframework.http.ResponseEntity; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.SerialId; @@ -45,7 +42,7 @@ import us.dot.its.jpo.ode.wrapper.MessageProducer; -public class TimDepositControllerTest { +class TimDepositControllerTest { @Tested TimDepositController testTimDepositController; @@ -72,26 +69,26 @@ public class TimDepositControllerTest { MessageProducer capturingMessageProducer; @Test - public void nullRequestShouldReturnEmptyError() { + void nullRequestShouldReturnEmptyError() { ResponseEntity actualResponse = testTimDepositController.postTim(null); assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); } @Test - public void emptyRequestShouldReturnEmptyError() { + void emptyRequestShouldReturnEmptyError() { ResponseEntity actualResponse = testTimDepositController.postTim(""); assertEquals("{\"error\":\"Empty request.\"}", actualResponse.getBody()); } @Test - public void invalidJsonSyntaxShouldReturnJsonSyntaxError() { + void invalidJsonSyntaxShouldReturnJsonSyntaxError() { ResponseEntity actualResponse = testTimDepositController.postTim("{\"in\"va}}}on\"}}"); assertEquals("{\"error\":\"Malformed or non-compliant JSON syntax.\"}", actualResponse.getBody()); } @Test - public void missingRequestElementShouldReturnMissingRequestError() { + void missingRequestElementShouldReturnMissingRequestError() { ResponseEntity actualResponse = testTimDepositController.postTim("{\"tim\":{}}"); assertEquals( "{\"error\":\"Missing or invalid argument: Request element is required as of version 3.\"}", @@ -99,7 +96,7 @@ public void missingRequestElementShouldReturnMissingRequestError() { } @Test - public void invalidTimestampShouldReturnInvalidTimestampError() { + void invalidTimestampShouldReturnInvalidTimestampError() { ResponseEntity actualResponse = testTimDepositController.postTim( "{\"request\":{},\"tim\":{\"timeStamp\":\"201-03-13T01:07:11-05:00\"}}"); assertEquals("{\"error\":\"Invalid timestamp in tim record: 201-03-13T01:07:11-05:00\"}", @@ -107,7 +104,7 @@ public void invalidTimestampShouldReturnInvalidTimestampError() { } @Test - public void messageWithNoRSUsOrSDWShouldReturnWarning() { + void messageWithNoRSUsOrSDWShouldReturnWarning() { ResponseEntity actualResponse = testTimDepositController.postTim( "{\"request\":{},\"tim\":{\"timeStamp\":\"2018-03-13T01:07:11-05:00\"}}"); assertEquals( @@ -116,8 +113,8 @@ public void messageWithNoRSUsOrSDWShouldReturnWarning() { } @Test - public void failedObjectNodeConversionShouldReturnConvertingError(@Capturing - TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) + void failedObjectNodeConversionShouldReturnConvertingError(@Capturing + TravelerMessageFromHumanToAsnConverter capturingTravelerMessageFromHumanToAsnConverter) throws JsonUtilsException, TravelerMessageFromHumanToAsnConverter.NoncompliantFieldsException { @@ -137,7 +134,7 @@ public void failedObjectNodeConversionShouldReturnConvertingError(@Capturing } @Test - public void failedXmlConversionShouldReturnConversionError( + void failedXmlConversionShouldReturnConversionError( @Capturing TimTransmogrifier capturingTimTransmogrifier) throws XmlUtilsException, JsonUtilsException { @@ -157,7 +154,7 @@ public void failedXmlConversionShouldReturnConversionError( } @Test - public void testSuccessfulMessageReturnsSuccessMessagePost( + void testSuccessfulMessageReturnsSuccessMessagePost( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { ResponseEntity actualResponse = testTimDepositController.postTim( @@ -166,7 +163,7 @@ public void testSuccessfulMessageReturnsSuccessMessagePost( } @Test - public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() throws Exception { + void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() throws Exception { String file = "/sdwRequest.json"; String json = IOUtils.toString(TimDepositControllerTest.class.getResourceAsStream(file), "UTF-8"); @@ -175,7 +172,7 @@ public void testSuccessfullSdwRequestMessageReturnsSuccessMessagePost() throws E } @Test - public void testSuccessfulMessageReturnsSuccessMessagePostWithOde( + void testSuccessfulMessageReturnsSuccessMessagePostWithOde( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { ResponseEntity actualResponse = testTimDepositController.postTim( @@ -184,7 +181,7 @@ public void testSuccessfulMessageReturnsSuccessMessagePostWithOde( } @Test - public void testSuccessfulMessageReturnsSuccessMessagePut( + void testSuccessfulMessageReturnsSuccessMessagePut( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { ResponseEntity actualResponse = testTimDepositController.putTim( @@ -193,7 +190,7 @@ public void testSuccessfulMessageReturnsSuccessMessagePut( } @Test - public void testDepositingTimWithExtraProperties( + void testDepositingTimWithExtraProperties( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = @@ -203,7 +200,7 @@ public void testDepositingTimWithExtraProperties( } @Test - public void testSuccessfulTimIngestIsTracked( + void testSuccessfulTimIngestIsTracked( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = @@ -215,7 +212,7 @@ public void testSuccessfulTimIngestIsTracked( } @Test - public void testSuccessfulRsuMessageReturnsSuccessMessagePost( + void testSuccessfulRsuMessageReturnsSuccessMessagePost( @Capturing TimTransmogrifier capturingTimTransmogrifier, @Capturing XmlUtils capturingXmlUtils) { String timToSubmit = diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index a97dd1ce0..052d16ef4 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -1,7 +1,25 @@ package us.dot.its.jpo.ode.traveler; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.Date; import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -11,7 +29,11 @@ import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; -import us.dot.its.jpo.ode.model.*; +import us.dot.its.jpo.ode.model.OdeMsgMetadata; +import us.dot.its.jpo.ode.model.OdeMsgPayload; +import us.dot.its.jpo.ode.model.OdeRequestMsgMetadata; +import us.dot.its.jpo.ode.model.OdeTravelerInputData; +import us.dot.its.jpo.ode.model.SerialId; import us.dot.its.jpo.ode.plugin.RoadSideUnit.RSU; import us.dot.its.jpo.ode.plugin.SNMP; import us.dot.its.jpo.ode.plugin.ServiceRequest; @@ -29,21 +51,6 @@ import us.dot.its.jpo.ode.util.XmlUtils; import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -import java.io.IOException; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Clock; -import java.time.Instant; -import java.time.ZoneId; -import java.util.Date; - -import static org.junit.jupiter.api.Assertions.*; - @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = RsuProperties.class) @@ -334,7 +341,7 @@ void testConstructorIsPrivate() throws NoSuchMethodException { } /** - * Helper method to prepare a SerialId object for testing + * Helper method to prepare a SerialId object for testing. * * @return a SerialId object */ @@ -345,7 +352,7 @@ private SerialId prepareSerialId() { } /** - * Helper method to prepare an OdeTravelerInputData object for testing + * Helper method to prepare an OdeTravelerInputData object for testing. * * @param timRequestContainingCircleGeometry a JSON string containing a TIM request with a circle geometry * @return an OdeTravelerInputData object @@ -358,7 +365,7 @@ private OdeTravelerInputData prepareOdeTID(String timRequestContainingCircleGeom } /** - * Helper method to prepare an OdeRequestMsgMetadata object for testing + * Helper method to prepare an OdeRequestMsgMetadata object for testing. * * @param odeTID an OdeTravelerInputData object * @param serialId a SerialId object @@ -379,9 +386,9 @@ private OdeRequestMsgMetadata prepareMetadata(OdeTravelerInputData odeTID, Seria Date latestStartDateTime = null; for (OdeTravelerInformationMessage.DataFrame dataFrameItem : tim.getDataframes()) { maxDurationTime = Math.max(maxDurationTime, dataFrameItem.getDurationTime()); - latestStartDateTime = latestStartDateTime == null || - latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) ? - dateFormat.parse(dataFrameItem.getStartDateTime()) : latestStartDateTime; + latestStartDateTime = latestStartDateTime == null + || latestStartDateTime.before(dateFormat.parse(dataFrameItem.getStartDateTime())) + ? dateFormat.parse(dataFrameItem.getStartDateTime()) : latestStartDateTime; } timMetadata.setMaxDurationTime(maxDurationTime); timMetadata.setOdeTimStartDateTime(dateFormat.format(latestStartDateTime)); From 48fea3a5b2c6b990a4e8de66ef244b456b9609e2 Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Sun, 8 Dec 2024 23:47:25 -0700 Subject: [PATCH 145/264] Regenerated TIM classes: Fix for sequence-of choice serialization to JSON, change license boilerplate to a non-javadoc comment at top of files. --- .../ode/plugin/j2735/addgrpb/DegreesLat.java | 44 ++-- .../ode/plugin/j2735/addgrpb/DegreesLong.java | 44 ++-- .../ode/plugin/j2735/addgrpb/Elevation.java | 44 ++-- .../addgrpb/LaneDataAttribute_addGrpB.java | 44 ++-- ...ttribute_addGrpBReg_LaneDataAttribute.java | 44 ++-- ...eg_LaneDataAttributeValueDeserializer.java | 38 ++- ...BReg_LaneDataAttributeValueSerializer.java | 38 ++- .../ode/plugin/j2735/addgrpb/LatitudeDMS.java | 44 ++-- .../plugin/j2735/addgrpb/LatitudeDMS2.java | 64 +++-- .../plugin/j2735/addgrpb/LongitudeDMS.java | 44 ++-- .../plugin/j2735/addgrpb/LongitudeDMS2.java | 64 +++-- .../plugin/j2735/addgrpb/MinutesAngle.java | 44 ++-- .../addgrpb/NodeOffsetPointXY_addGrpB.java | 63 +++-- ...tPointXY_addGrpBReg_NodeOffsetPointXY.java | 44 ++-- ...eg_NodeOffsetPointXYValueDeserializer.java | 38 ++- ...BReg_NodeOffsetPointXYValueSerializer.java | 38 ++- .../plugin/j2735/addgrpb/Node_LLdms_48b.java | 60 +++-- .../plugin/j2735/addgrpb/Node_LLdms_80b.java | 57 ++--- .../j2735/addgrpb/Position3D_addGrpB.java | 62 ++--- .../Position3D_addGrpBReg_Position3D.java | 44 ++-- ...ddGrpBReg_Position3DValueDeserializer.java | 38 ++- ..._addGrpBReg_Position3DValueSerializer.java | 38 ++- .../plugin/j2735/addgrpb/SecondsAngle.java | 44 ++-- .../ode/plugin/j2735/addgrpc/Altitude.java | 59 +++-- .../j2735/addgrpc/AltitudeConfidence.java | 44 ++-- .../AltitudeConfidenceDeserializer.java | 38 ++- .../addgrpc/AltitudeConfidenceSerializer.java | 38 ++- .../plugin/j2735/addgrpc/AltitudeValue.java | 44 ++-- .../j2735/addgrpc/Position3D_addGrpC.java | 54 ++--- .../Position3D_addGrpCReg_Position3D.java | 44 ++-- ...ddGrpCReg_Position3DValueDeserializer.java | 38 ++- ..._addGrpCReg_Position3DValueSerializer.java | 38 ++- .../jpo/ode/plugin/j2735/common/Angle.java | 44 ++-- .../ode/plugin/j2735/common/ComputedLane.java | 108 ++++----- .../jpo/ode/plugin/j2735/common/DYear.java | 44 ++-- .../ode/plugin/j2735/common/DeltaAngle.java | 44 ++-- .../plugin/j2735/common/DescriptiveName.java | 40 ++-- .../j2735/common/DrivenLineOffsetLg.java | 44 ++-- .../j2735/common/DrivenLineOffsetSm.java | 44 ++-- .../ode/plugin/j2735/common/Elevation.java | 44 ++-- .../jpo/ode/plugin/j2735/common/Extent.java | 44 ++-- .../j2735/common/ExtentDeserializer.java | 38 ++- .../plugin/j2735/common/ExtentSerializer.java | 38 ++- .../plugin/j2735/common/FurtherInfoID.java | 48 ++-- .../ode/plugin/j2735/common/HeadingSlice.java | 40 ++-- .../common/HeadingSliceDeserializer.java | 38 ++- .../j2735/common/LaneDataAttribute.java | 92 ++++---- .../j2735/common/LaneDataAttributeList.java | 65 ++++-- .../jpo/ode/plugin/j2735/common/LaneID.java | 44 ++-- .../ode/plugin/j2735/common/LaneWidth.java | 44 ++-- .../jpo/ode/plugin/j2735/common/Latitude.java | 44 ++-- .../ode/plugin/j2735/common/Longitude.java | 44 ++-- .../j2735/common/MergeDivergeNodeAngle.java | 44 ++-- .../plugin/j2735/common/MinuteOfTheYear.java | 44 ++-- .../jpo/ode/plugin/j2735/common/MsgCount.java | 44 ++-- .../j2735/common/NodeAttributeSetXY.java | 82 +++---- .../plugin/j2735/common/NodeAttributeXY.java | 44 ++-- .../common/NodeAttributeXYDeserializer.java | 38 ++- .../j2735/common/NodeAttributeXYList.java | 44 ++-- .../common/NodeAttributeXYSerializer.java | 38 ++- .../ode/plugin/j2735/common/NodeListXY.java | 67 +++--- .../j2735/common/NodeOffsetPointXY.java | 63 +++-- .../ode/plugin/j2735/common/NodeSetXY.java | 42 ++-- .../jpo/ode/plugin/j2735/common/NodeXY.java | 57 ++--- .../plugin/j2735/common/Node_LLmD_64b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_20b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_22b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_24b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_26b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_28b.java | 60 +++-- .../ode/plugin/j2735/common/Node_XY_32b.java | 60 +++-- .../ode/plugin/j2735/common/OffsetLL_B12.java | 44 ++-- .../ode/plugin/j2735/common/OffsetLL_B14.java | 44 ++-- .../ode/plugin/j2735/common/OffsetLL_B16.java | 44 ++-- .../ode/plugin/j2735/common/OffsetLL_B18.java | 44 ++-- .../ode/plugin/j2735/common/OffsetLL_B22.java | 44 ++-- .../ode/plugin/j2735/common/OffsetLL_B24.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B10.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B11.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B12.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B13.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B14.java | 44 ++-- .../ode/plugin/j2735/common/Offset_B16.java | 44 ++-- .../ode/plugin/j2735/common/Position3D.java | 65 +++--- .../jpo/ode/plugin/j2735/common/RegionId.java | 44 ++-- .../j2735/common/RegionalExtension.java | 44 ++-- .../j2735/common/RegulatorySpeedLimit.java | 59 +++-- .../plugin/j2735/common/RoadRegulatorID.java | 44 ++-- .../plugin/j2735/common/RoadSegmentID.java | 44 ++-- .../j2735/common/RoadSegmentReferenceID.java | 60 +++-- .../j2735/common/RoadwayCrownAngle.java | 44 ++-- .../jpo/ode/plugin/j2735/common/SSPindex.java | 44 ++-- .../ode/plugin/j2735/common/Scale_B12.java | 44 ++-- .../j2735/common/SegmentAttributeXY.java | 44 ++-- .../SegmentAttributeXYDeserializer.java | 38 ++- .../j2735/common/SegmentAttributeXYList.java | 44 ++-- .../common/SegmentAttributeXYSerializer.java | 38 ++- .../plugin/j2735/common/SpeedLimitList.java | 42 ++-- .../plugin/j2735/common/SpeedLimitType.java | 44 ++-- .../common/SpeedLimitTypeDeserializer.java | 38 ++- .../common/SpeedLimitTypeSerializer.java | 38 ++- .../jpo/ode/plugin/j2735/common/Velocity.java | 44 ++-- .../j2735/travelerinformation/Circle.java | 64 ++--- .../travelerinformation/DirectionOfUse.java | 44 ++-- .../DirectionOfUseDeserializer.java | 38 ++- .../DirectionOfUseSerializer.java | 38 ++- .../travelerinformation/DistanceUnits.java | 44 ++-- .../DistanceUnitsDeserializer.java | 38 ++- .../DistanceUnitsSerializer.java | 38 ++- .../travelerinformation/ExitService.java | 42 ++-- .../ExitServiceSequence.java | 74 +++--- .../travelerinformation/GenericSignage.java | 42 ++-- .../GenericSignageSequence.java | 74 +++--- .../travelerinformation/GeographicalPath.java | 101 ++++---- .../GeometricProjection.java | 74 +++--- .../travelerinformation/ITIStextPhrase.java | 40 ++-- .../j2735/travelerinformation/MUTCDCode.java | 44 ++-- .../MUTCDCodeDeserializer.java | 38 ++- .../MUTCDCodeSerializer.java | 38 ++- .../travelerinformation/MinutesDuration.java | 44 ++-- .../j2735/travelerinformation/MsgCRC.java | 48 ++-- .../travelerinformation/NodeAttributeLL.java | 44 ++-- .../NodeAttributeLLDeserializer.java | 38 ++- .../NodeAttributeLLList.java | 44 ++-- .../NodeAttributeLLSerializer.java | 38 ++- .../NodeAttributeSetLL.java | 86 +++---- .../j2735/travelerinformation/NodeLL.java | 57 ++--- .../j2735/travelerinformation/NodeListLL.java | 64 +++-- .../NodeOffsetPointLL.java | 65 +++--- .../j2735/travelerinformation/NodeSetLL.java | 42 ++-- .../travelerinformation/Node_LL_24B.java | 62 +++-- .../travelerinformation/Node_LL_28B.java | 62 +++-- .../travelerinformation/Node_LL_32B.java | 62 +++-- .../travelerinformation/Node_LL_36B.java | 62 +++-- .../travelerinformation/Node_LL_44B.java | 62 +++-- .../travelerinformation/Node_LL_48B.java | 62 +++-- .../travelerinformation/OffsetSystem.java | 75 +++--- .../j2735/travelerinformation/Radius_B12.java | 44 ++-- .../j2735/travelerinformation/RegionList.java | 42 ++-- .../travelerinformation/RegionOffsets.java | 66 +++--- .../travelerinformation/RegionPointSet.java | 68 +++--- .../j2735/travelerinformation/RoadSignID.java | 67 +++--- .../SegmentAttributeLL.java | 44 ++-- .../SegmentAttributeLLDeserializer.java | 38 ++- .../SegmentAttributeLLList.java | 44 ++-- .../SegmentAttributeLLSerializer.java | 38 ++- .../travelerinformation/ShapePointSet.java | 71 +++--- .../travelerinformation/SignPrority.java | 44 ++-- .../j2735/travelerinformation/SpeedLimit.java | 42 ++-- .../SpeedLimitSequence.java | 74 +++--- .../TravelerDataFrame.java | 148 ++++++------ .../TravelerDataFrame.java.bak | 218 ++++++++++++++++++ .../TravelerDataFrameList.java | 42 ++-- .../travelerinformation/TravelerInfoType.java | 44 ++-- .../TravelerInfoTypeDeserializer.java | 38 ++- .../TravelerInfoTypeSerializer.java | 38 ++- .../TravelerInformation.java | 84 +++---- .../TravelerInformation.java.bak | 79 +++++++ .../j2735/travelerinformation/URL_Base.java | 40 ++-- .../j2735/travelerinformation/URL_Short.java | 40 ++-- .../travelerinformation/UniqueMSGID.java | 48 ++-- .../travelerinformation/ValidRegion.java | 81 ++++--- .../j2735/travelerinformation/WorkZone.java | 42 ++-- .../travelerinformation/WorkZoneSequence.java | 74 +++--- .../j2735/travelerinformation/Zoom.java | 44 ++-- .../serialization/IntegerDeserializer.java | 8 +- .../serialization/OpenTypeDeserializer.java | 28 +-- .../SequenceOfChoiceDeserializer.java | 64 +++++ .../SequenceOfChoiceSerializer.java | 54 +++++ .../its/jpo/ode/plugin/types/Asn1Choice.java | 32 --- .../jpo/ode/plugin/types/Asn1OctetString.java | 23 +- .../its/jpo/ode/plugin/utils/XmlUtils.java | 169 ++++++++++++++ .../NodeAttributeSetLLTest.java | 1 + 173 files changed, 4596 insertions(+), 4300 deletions(-) create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java.bak create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java.bak create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceDeserializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceSerializer.java create mode 100644 jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/XmlUtils.java diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java index ff18a437c..4c66201d8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLat.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DegreesLat.DegreesLatDeserializer.class) public class DegreesLat extends Asn1Integer { public DegreesLat() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java index 5dccdd43c..806a15a72 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/DegreesLong.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DegreesLong.DegreesLongDeserializer.class) public class DegreesLong extends Asn1Integer { public DegreesLong() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java index 10fea8d79..9b27d5a6d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Elevation.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Elevation.ElevationDeserializer.class) public class Elevation extends Asn1Integer { public Elevation() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java index ab7e1bb75..139ba44bb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpB.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class LaneDataAttribute_addGrpB extends Asn1Sequence { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java index 95943a384..21b1949a6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttribute.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; + @JsonRootName("Reg_LaneDataAttribute") public class LaneDataAttribute_addGrpBReg_LaneDataAttribute extends Reg_LaneDataAttribute { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java index 4ffa829a2..190be26c6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueDeserializer extends OpenTypeDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java index 3b81922f9..0c965b5d7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + public class LaneDataAttribute_addGrpBReg_LaneDataAttributeValueSerializer extends OpenTypeSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java index 39c9544b8..7d22d8885 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = LatitudeDMS.LatitudeDMSDeserializer.class) public class LatitudeDMS extends Asn1Integer { public LatitudeDMS() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java index 96b95f99f..87f3ece8a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LatitudeDMS2.java @@ -1,52 +1,50 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class LatitudeDMS2 extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = DegreesLat.DegreesLatDeserializer.class) + @Asn1Property(tag = 0, name = "d") + @JsonProperty("d") private DegreesLat d; - @Asn1Property(tag = 1) - @JsonDeserialize(using = MinutesAngle.MinutesAngleDeserializer.class) + @Asn1Property(tag = 1, name = "m") + @JsonProperty("m") private MinutesAngle m; - @Asn1Property(tag = 2) - @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) + @Asn1Property(tag = 2, name = "s") + @JsonProperty("s") private SecondsAngle s; LatitudeDMS2() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java index 684a69bd7..446d42a29 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = LongitudeDMS.LongitudeDMSDeserializer.class) public class LongitudeDMS extends Asn1Integer { public LongitudeDMS() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java index 3f6ea906b..0910002ee 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/LongitudeDMS2.java @@ -1,52 +1,50 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class LongitudeDMS2 extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = DegreesLong.DegreesLongDeserializer.class) + @Asn1Property(tag = 0, name = "d") + @JsonProperty("d") private DegreesLong d; - @Asn1Property(tag = 1) - @JsonDeserialize(using = MinutesAngle.MinutesAngleDeserializer.class) + @Asn1Property(tag = 1, name = "m") + @JsonProperty("m") private MinutesAngle m; - @Asn1Property(tag = 2) - @JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) + @Asn1Property(tag = 2, name = "s") + @JsonProperty("s") private SecondsAngle s; LongitudeDMS2() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java index 0d0a221b1..64185accd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/MinutesAngle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = MinutesAngle.MinutesAngleDeserializer.class) public class MinutesAngle extends Asn1Integer { public MinutesAngle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java index 604133f8a..6f95a8624 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpB.java @@ -1,55 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; + @Getter @Setter @JsonInclude(Include.NON_NULL) public class NodeOffsetPointXY_addGrpB extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "posA") + @JsonProperty("posA") private Node_LLdms_48b posA; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "posB") + @JsonProperty("posB") private Node_LLdms_80b posB; NodeOffsetPointXY_addGrpB() { super(true); } - - @Override - protected List> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java index 1555a9d9e..f0761bbe0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; + @JsonRootName("Reg_NodeOffsetPointXY") public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY extends Reg_NodeOffsetPointXY { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java index 5dc245e26..ff088be19 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueDeserializer extends OpenTypeDeserializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java index 00e8dbb98..7badc4375 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + public class NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXYValueSerializer extends OpenTypeSerializer { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java index 1713a3328..148dc3911 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_48b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LLdms_48b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = LongitudeDMS.LongitudeDMSDeserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private LongitudeDMS lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = LatitudeDMS.LatitudeDMSDeserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private LatitudeDMS lat; Node_LLdms_48b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java index 36fac5ed0..ec3f30e2a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Node_LLdms_80b.java @@ -1,46 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LLdms_80b extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private LongitudeDMS2 lon; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private LatitudeDMS2 lat; Node_LLdms_80b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java index 5b8146824..4d142da73 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpB.java @@ -1,50 +1,50 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Position3D_addGrpB extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "latitude") + @JsonProperty("latitude") private LatitudeDMS2 latitude; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "longitude") + @JsonProperty("longitude") private LongitudeDMS2 longitude; - @Asn1Property(tag = 2) - @JsonDeserialize(using = Elevation.ElevationDeserializer.class) + @Asn1Property(tag = 2, name = "elevation") + @JsonProperty("elevation") private Elevation elevation; Position3D_addGrpB() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java index 04ecf4e39..5835c0fa2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3D.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; + @JsonRootName("Reg_Position3D") public class Position3D_addGrpBReg_Position3D extends Reg_Position3D { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java index e2107d551..07b4b9cbb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + public class Position3D_addGrpBReg_Position3DValueDeserializer extends OpenTypeDeserializer { public Position3D_addGrpBReg_Position3DValueDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java index 2103b40b8..75716ef60 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/Position3D_addGrpBReg_Position3DValueSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + public class Position3D_addGrpBReg_Position3DValueSerializer extends OpenTypeSerializer { public Position3D_addGrpBReg_Position3DValueSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java index 8178aa106..85e834711 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpb/SecondsAngle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpb; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpb; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = SecondsAngle.SecondsAngleDeserializer.class) public class SecondsAngle extends Asn1Integer { public SecondsAngle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java index fe678d880..373260db5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Altitude.java @@ -1,48 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Altitude extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = AltitudeValue.AltitudeValueDeserializer.class) + @Asn1Property(tag = 0, name = "value") + @JsonProperty("value") private AltitudeValue value; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "confidence") + @JsonProperty("confidence") private AltitudeConfidence confidence; Altitude() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java index 2039629f6..e31e49a18 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidence.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = AltitudeConfidenceSerializer.class) @JsonDeserialize(using = AltitudeConfidenceDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java index c12e33d2d..7c2abec91 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class AltitudeConfidenceDeserializer extends EnumeratedDeserializer { AltitudeConfidenceDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java index f24b494d7..3b61bfe57 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeConfidenceSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class AltitudeConfidenceSerializer extends EnumeratedSerializer { AltitudeConfidenceSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java index d7c7ba0e3..a5daab0bc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/AltitudeValue.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = AltitudeValue.AltitudeValueDeserializer.class) public class AltitudeValue extends Asn1Integer { public AltitudeValue() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java index 85c0dfa1f..95bef32f1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpC.java @@ -1,44 +1,44 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Position3D_addGrpC extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "altitude") + @JsonProperty("altitude") private Altitude altitude; Position3D_addGrpC() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java index 3a09e4f61..c8f51150b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3D.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import com.fasterxml.jackson.annotation.JsonRootName; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import com.fasterxml.jackson.annotation.JsonRootName; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; + @JsonRootName("Reg_Position3D") public class Position3D_addGrpCReg_Position3D extends Reg_Position3D { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java index f4871f3dd..63b9c925a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeDeserializer; + public class Position3D_addGrpCReg_Position3DValueDeserializer extends OpenTypeDeserializer { public Position3D_addGrpCReg_Position3DValueDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java index dba7643ba..089b586f9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/addgrpc/Position3D_addGrpCReg_Position3DValueSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.addgrpc; - -import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.addgrpc; + +import us.dot.its.jpo.ode.plugin.serialization.OpenTypeSerializer; + public class Position3D_addGrpCReg_Position3DValueSerializer extends OpenTypeSerializer { public Position3D_addGrpCReg_Position3DValueSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java index a4b45ab87..86182260b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Angle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Angle.AngleDeserializer.class) public class Angle extends Asn1Integer { public Angle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java index 1e8169cd9..b93094c46 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ComputedLane.java @@ -1,109 +1,97 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.common; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; import us.dot.its.jpo.ode.plugin.j2735.region.Reg_ComputedLane; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class ComputedLane extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = LaneID.LaneIDDeserializer.class) + @Asn1Property(tag = 0, name = "referenceLaneId") + @JsonProperty("referenceLaneId") private LaneID referenceLaneId; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "offsetXaxis") + @JsonProperty("offsetXaxis") private OffsetXaxisChoice offsetXaxis; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "offsetYaxis") + @JsonProperty("offsetYaxis") private OffsetYaxisChoice offsetYaxis; - @Asn1Property(tag = 3, optional = true) - @JsonDeserialize(using = Angle.AngleDeserializer.class) + @Asn1Property(tag = 3, name = "rotateXY", optional = true) + @JsonProperty("rotateXY") private Angle rotateXY; - @Asn1Property(tag = 4, optional = true) - @JsonDeserialize(using = Scale_B12.Scale_B12Deserializer.class) + @Asn1Property(tag = 4, name = "scaleXaxis", optional = true) + @JsonProperty("scaleXaxis") private Scale_B12 scaleXaxis; - @Asn1Property(tag = 5, optional = true) - @JsonDeserialize(using = Scale_B12.Scale_B12Deserializer.class) + @Asn1Property(tag = 5, name = "scaleYaxis", optional = true) + @JsonProperty("scaleYaxis") private Scale_B12 scaleYaxis; - @Asn1Property(tag = 6, optional = true) + @Asn1Property(tag = 6, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class OffsetXaxisChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = DrivenLineOffsetSm.DrivenLineOffsetSmDeserializer.class) + @Asn1Property(tag = 0, name = "small") + @JsonProperty("small") private DrivenLineOffsetSm small; - @Asn1Property(tag = 1) - @JsonDeserialize(using = DrivenLineOffsetLg.DrivenLineOffsetLgDeserializer.class) + @Asn1Property(tag = 1, name = "large") + @JsonProperty("large") private DrivenLineOffsetLg large; OffsetXaxisChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } @Getter @Setter @JsonInclude(Include.NON_NULL) public static class OffsetYaxisChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = DrivenLineOffsetSm.DrivenLineOffsetSmDeserializer.class) + @Asn1Property(tag = 0, name = "small") + @JsonProperty("small") private DrivenLineOffsetSm small; - @Asn1Property(tag = 1) - @JsonDeserialize(using = DrivenLineOffsetLg.DrivenLineOffsetLgDeserializer.class) + @Asn1Property(tag = 1, name = "large") + @JsonProperty("large") private DrivenLineOffsetLg large; OffsetYaxisChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java index 17c229bb9..bf4ce23f5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DYear.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DYear.DYearDeserializer.class) public class DYear extends Asn1Integer { public DYear() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java index 3dcecb25d..e28d2e173 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DeltaAngle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DeltaAngle.DeltaAngleDeserializer.class) public class DeltaAngle extends Asn1Integer { public DeltaAngle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java index fcb3562d8..a292428b2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DescriptiveName.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.IA5String; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.types.IA5String; + public class DescriptiveName extends IA5String { public DescriptiveName() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java index 2a1693bf1..046a5b74b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetLg.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DrivenLineOffsetLg.DrivenLineOffsetLgDeserializer.class) public class DrivenLineOffsetLg extends Asn1Integer { public DrivenLineOffsetLg() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java index 321f5e403..af6fd6530 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/DrivenLineOffsetSm.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = DrivenLineOffsetSm.DrivenLineOffsetSmDeserializer.class) public class DrivenLineOffsetSm extends Asn1Integer { public DrivenLineOffsetSm() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java index c1a2dd49f..8cc6ad4d3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Elevation.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Elevation.ElevationDeserializer.class) public class Elevation extends Asn1Integer { public Elevation() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java index 4c37d2047..4cac2a61e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Extent.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = ExtentSerializer.class) @JsonDeserialize(using = ExtentDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java index e2552a24d..e976def33 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class ExtentDeserializer extends EnumeratedDeserializer { ExtentDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java index 58a9f53e6..b527d6de2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/ExtentSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class ExtentSerializer extends EnumeratedSerializer { ExtentSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java index f6e89eeff..8e77ca552 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/FurtherInfoID.java @@ -1,44 +1,38 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ -public class FurtherInfoID extends Asn1OctetString { + *============================================================================*/ - private String value; +package us.dot.its.jpo.ode.plugin.j2735.common; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; + +public class FurtherInfoID extends Asn1OctetString { + + @JsonValue public String getValue() { return value; } - public void setValue(String value) { - this.value = value; - } - @Override public String toString() { return value; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java index 2d79f0c9c..11c739dc5 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSlice.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.types.Asn1Bitstring; + @JsonDeserialize(using = HeadingSliceDeserializer.class) public class HeadingSlice extends Asn1Bitstring { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java index d2ff8085c..9cff89dcb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/HeadingSliceDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.BitStringDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.BitStringDeserializer; + public class HeadingSliceDeserializer extends BitStringDeserializer { HeadingSliceDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java index eb41a08cf..338070217 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttribute.java @@ -1,69 +1,66 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_LaneDataAttribute; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @Getter @Setter @JsonInclude(Include.NON_NULL) public class LaneDataAttribute extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = DeltaAngle.DeltaAngleDeserializer.class) + @Asn1Property(tag = 0, name = "pathEndPointAngle") + @JsonProperty("pathEndPointAngle") private DeltaAngle pathEndPointAngle; - @Asn1Property(tag = 1) - @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + @Asn1Property(tag = 1, name = "laneCrownPointCenter") + @JsonProperty("laneCrownPointCenter") private RoadwayCrownAngle laneCrownPointCenter; - @Asn1Property(tag = 2) - @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + @Asn1Property(tag = 2, name = "laneCrownPointLeft") + @JsonProperty("laneCrownPointLeft") private RoadwayCrownAngle laneCrownPointLeft; - @Asn1Property(tag = 3) - @JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) + @Asn1Property(tag = 3, name = "laneCrownPointRight") + @JsonProperty("laneCrownPointRight") private RoadwayCrownAngle laneCrownPointRight; - @Asn1Property(tag = 4) - @JsonDeserialize(using = MergeDivergeNodeAngle.MergeDivergeNodeAngleDeserializer.class) + @Asn1Property(tag = 4, name = "laneAngle") + @JsonProperty("laneAngle") private MergeDivergeNodeAngle laneAngle; - @Asn1Property(tag = 5) + @Asn1Property(tag = 5, name = "speedLimits") + @JsonProperty("speedLimits") @JacksonXmlElementWrapper(localName = "speedLimits") @JacksonXmlProperty(localName = "RegulatorySpeedLimit") private SpeedLimitList speedLimits; - @Asn1Property(tag = 6) + @Asn1Property(tag = 6, name = "regional") + @JsonProperty("regional") private SequenceOfRegional regional; LaneDataAttribute() { @@ -76,9 +73,4 @@ public static class SequenceOfRegional extends Asn1SequenceOf> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java index 22af32c0a..f36ecf60b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneDataAttributeList.java @@ -1,37 +1,58 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfChoiceDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfChoiceSerializer; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class LaneDataAttributeList extends Asn1SequenceOf { LaneDataAttributeList() { super(LaneDataAttribute.class, 1L, 8L); } + + public static class LaneDataAttributeListSerializer + extends + SequenceOfChoiceSerializer { + public LaneDataAttributeListSerializer() { + super(LaneDataAttribute.class, LaneDataAttributeList.class); + } + } + + public static class LaneDataAttributeListDeserializer + extends + SequenceOfChoiceDeserializer { + public LaneDataAttributeListDeserializer() { + super(LaneDataAttribute.class, LaneDataAttributeList.class); + } + + @Override + protected LaneDataAttributeList construct() { + return new LaneDataAttributeList(); + } + } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java index d936442fd..2cdc7d309 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneID.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = LaneID.LaneIDDeserializer.class) public class LaneID extends Asn1Integer { public LaneID() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java index 9501bbc96..1f9ab714b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/LaneWidth.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) public class LaneWidth extends Asn1Integer { public LaneWidth() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java index 22137e9eb..bfe2934cc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Latitude.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Latitude.LatitudeDeserializer.class) public class Latitude extends Asn1Integer { public Latitude() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java index 4184924b0..cced10041 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Longitude.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Longitude.LongitudeDeserializer.class) public class Longitude extends Asn1Integer { public Longitude() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java index 19c61d8ae..745000a76 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MergeDivergeNodeAngle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = MergeDivergeNodeAngle.MergeDivergeNodeAngleDeserializer.class) public class MergeDivergeNodeAngle extends Asn1Integer { public MergeDivergeNodeAngle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java index e2bd1edf4..9fafa1ee4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MinuteOfTheYear.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) public class MinuteOfTheYear extends Asn1Integer { public MinuteOfTheYear() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java index 98f1c6fb8..db6e65709 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/MsgCount.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = MsgCount.MsgCountDeserializer.class) public class MsgCount extends Asn1Integer { public MsgCount() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java index af3fd9034..bf41d4a69 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeSetXY.java @@ -1,71 +1,71 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.common; -import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeAttributeSetXY; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -/** - * - * EDITED: Add @JsonProperty annotations to dWidth and dElevation - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class NodeAttributeSetXY extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) + @Asn1Property(tag = 0, name = "localNode", optional = true) + @JsonProperty("localNode") @JsonDeserialize(using = NodeAttributeXYList.NodeAttributeXYListDeserializer.class) private NodeAttributeXYList localNode; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "disabled", optional = true) + @JsonProperty("disabled") @JsonDeserialize(using = SegmentAttributeXYList.SegmentAttributeXYListDeserializer.class) private SegmentAttributeXYList disabled; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "enabled", optional = true) + @JsonProperty("enabled") @JsonDeserialize(using = SegmentAttributeXYList.SegmentAttributeXYListDeserializer.class) private SegmentAttributeXYList enabled; - @Asn1Property(tag = 3, optional = true) - @JacksonXmlElementWrapper(useWrapping = false) + @Asn1Property(tag = 3, name = "data", optional = true) + @JsonProperty("data") + @JsonSerialize(using = LaneDataAttributeList.LaneDataAttributeListSerializer.class) + @JsonDeserialize(using = LaneDataAttributeList.LaneDataAttributeListDeserializer.class) private LaneDataAttributeList data; - @Asn1Property(tag = 4, optional = true) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 4, name = "dWidth", optional = true) @JsonProperty("dWidth") private Offset_B10 dWidth; - @Asn1Property(tag = 5, optional = true) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 5, name = "dElevation", optional = true) @JsonProperty("dElevation") private Offset_B10 dElevation; - @Asn1Property(tag = 6, optional = true) + @Asn1Property(tag = 6, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java index fa99c7604..b6a1fa214 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXY.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = NodeAttributeXYSerializer.class) @JsonDeserialize(using = NodeAttributeXYDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java index 0259fc5dc..fc9c89a7d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class NodeAttributeXYDeserializer extends EnumeratedDeserializer { NodeAttributeXYDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java index 18cac154a..268bcbce9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYList.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class NodeAttributeXYList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java index b463c0300..a7136a038 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeAttributeXYSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class NodeAttributeXYSerializer extends EnumeratedSerializer { NodeAttributeXYSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java index 34bf65551..f282ae0dd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeListXY.java @@ -1,59 +1,52 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; + @Getter @Setter @JsonInclude(Include.NON_NULL) public class NodeListXY extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "nodes") + @JsonProperty("nodes") @JacksonXmlElementWrapper(localName = "nodes") @JacksonXmlProperty(localName = "NodeXY") private NodeSetXY nodes; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "computed") + @JsonProperty("computed") private ComputedLane computed; NodeListXY() { super(true); } - - @Override - protected List> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java index f0bd1b166..15e9580f8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeOffsetPointXY.java @@ -1,41 +1,36 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointXY; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; + @Getter @Setter @JsonInclude(Include.NON_NULL) @@ -62,15 +57,11 @@ public class NodeOffsetPointXY extends Asn1Choice { @Asn1Property(tag = 6, name = "node-LatLon") @JsonProperty("node-LatLon") private Node_LLmD_64b node_LatLon; - @Asn1Property(tag = 7) + @Asn1Property(tag = 7, name = "regional") + @JsonProperty("regional") private Reg_NodeOffsetPointXY regional; NodeOffsetPointXY() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java index b7dfa2aa7..84aee9819 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeSetXY.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class NodeSetXY extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java index b6cc8a04b..7f03d2dd8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/NodeXY.java @@ -1,46 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class NodeXY extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "delta") + @JsonProperty("delta") private NodeOffsetPointXY delta; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "attributes", optional = true) + @JsonProperty("attributes") private NodeAttributeSetXY attributes; NodeXY() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java index 59055849e..c2821a4be 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_LLmD_64b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LLmD_64b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Longitude.LongitudeDeserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private Longitude lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Latitude.LatitudeDeserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private Latitude lat; Node_LLmD_64b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java index d0066ba70..e3f6e6839 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_20b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_20b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B10 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B10 y; Node_XY_20b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java index 919cf175b..a3db0c627 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_22b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_22b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B11 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B11 y; Node_XY_22b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java index a43dc1063..031a838d9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_24b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_24b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B12 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B12 y; Node_XY_24b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java index a1a51aa56..5673f4500 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_26b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_26b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B13 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B13 y; Node_XY_26b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java index 3e1a7286b..4e564c216 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_28b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_28b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B14 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B14 y; Node_XY_28b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java index dac1b425c..a5daac524 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Node_XY_32b.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_XY_32b extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) + @Asn1Property(tag = 0, name = "x") + @JsonProperty("x") private Offset_B16 x; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) + @Asn1Property(tag = 1, name = "y") + @JsonProperty("y") private Offset_B16 y; Node_XY_32b() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java index 252e7b646..136a05af4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B12.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) public class OffsetLL_B12 extends Asn1Integer { public OffsetLL_B12() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java index a80b1baa1..82a886edc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B14.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) public class OffsetLL_B14 extends Asn1Integer { public OffsetLL_B14() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java index ed1d6b972..3a3bd1626 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B16.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) public class OffsetLL_B16 extends Asn1Integer { public OffsetLL_B16() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java index 00390c1a2..962e8d970 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B18.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) public class OffsetLL_B18 extends Asn1Integer { public OffsetLL_B18() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java index ab1a3fb3f..07e064f6d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B22.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) public class OffsetLL_B22 extends Asn1Integer { public OffsetLL_B22() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java index 5c9f8ac1f..c37701e28 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/OffsetLL_B24.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) public class OffsetLL_B24 extends Asn1Integer { public OffsetLL_B24() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java index b690c2a6d..2ab269382 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B10.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) public class Offset_B10 extends Asn1Integer { public Offset_B10() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java index e61837b32..0d3c7f4a6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B11.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B11.Offset_B11Deserializer.class) public class Offset_B11 extends Asn1Integer { public Offset_B11() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java index 0d8616b48..a2762e17a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B12.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B12.Offset_B12Deserializer.class) public class Offset_B12 extends Asn1Integer { public Offset_B12() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java index b1deca14a..c022692d7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B13.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B13.Offset_B13Deserializer.class) public class Offset_B13 extends Asn1Integer { public Offset_B13() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java index 98f41e859..c11562014 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B14.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B14.Offset_B14Deserializer.class) public class Offset_B14 extends Asn1Integer { public Offset_B14() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java index 118af18cd..a43cb611d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Offset_B16.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Offset_B16.Offset_B16Deserializer.class) public class Offset_B16 extends Asn1Integer { public Offset_B16() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java index 981acd100..fa2e7d007 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Position3D.java @@ -1,58 +1,55 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.common; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.annotation.JsonProperty; import us.dot.its.jpo.ode.plugin.j2735.region.Reg_Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Position3D extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = Latitude.LatitudeDeserializer.class) + @Asn1Property(tag = 0, name = "lat") + @JsonProperty("lat") private Latitude lat; @Asn1Property(tag = 1, name = "long") @JsonProperty("long") - @JsonDeserialize(using = Longitude.LongitudeDeserializer.class) private Longitude long_; - @Asn1Property(tag = 2, optional = true) - @JsonDeserialize(using = Elevation.ElevationDeserializer.class) + @Asn1Property(tag = 2, name = "elevation", optional = true) + @JsonProperty("elevation") private Elevation elevation; - @Asn1Property(tag = 3, optional = true) + @Asn1Property(tag = 3, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java index b4e67d810..2a7f9ee57 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionId.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = RegionId.RegionIdDeserializer.class) public class RegionId extends Asn1Integer { public RegionId() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java index 3fd317611..46ddec790 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegionalExtension.java @@ -1,38 +1,34 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + abstract public class RegionalExtension extends Asn1Sequence { @JsonIgnore - @JsonDeserialize(using = RegionId.RegionIdDeserializer.class) final protected RegionId regionId; @JsonIgnore final protected String name; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java index 4c614a605..a1420bfa3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RegulatorySpeedLimit.java @@ -1,48 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class RegulatorySpeedLimit extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "type") + @JsonProperty("type") private SpeedLimitType type; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Velocity.VelocityDeserializer.class) + @Asn1Property(tag = 1, name = "speed") + @JsonProperty("speed") private Velocity speed; RegulatorySpeedLimit() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java index c6306bd10..aaa28cee9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadRegulatorID.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = RoadRegulatorID.RoadRegulatorIDDeserializer.class) public class RoadRegulatorID extends Asn1Integer { public RoadRegulatorID() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java index f17376267..b0b71f2fe 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentID.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = RoadSegmentID.RoadSegmentIDDeserializer.class) public class RoadSegmentID extends Asn1Integer { public RoadSegmentID() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java index a8c1bfdaa..67240b99e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadSegmentReferenceID.java @@ -1,49 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class RoadSegmentReferenceID extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) - @JsonDeserialize(using = RoadRegulatorID.RoadRegulatorIDDeserializer.class) + @Asn1Property(tag = 0, name = "region", optional = true) + @JsonProperty("region") private RoadRegulatorID region; - @Asn1Property(tag = 1) - @JsonDeserialize(using = RoadSegmentID.RoadSegmentIDDeserializer.class) + @Asn1Property(tag = 1, name = "id") + @JsonProperty("id") private RoadSegmentID id; RoadSegmentReferenceID() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java index 8d9d168f6..7e8499597 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/RoadwayCrownAngle.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = RoadwayCrownAngle.RoadwayCrownAngleDeserializer.class) public class RoadwayCrownAngle extends Asn1Integer { public RoadwayCrownAngle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java index 10a9e6fdc..44bf449eb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SSPindex.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) public class SSPindex extends Asn1Integer { public SSPindex() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java index 2d22269be..3aae74343 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Scale_B12.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Scale_B12.Scale_B12Deserializer.class) public class Scale_B12 extends Asn1Integer { public Scale_B12() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java index 47d517b09..763cb2586 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXY.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = SegmentAttributeXYSerializer.class) @JsonDeserialize(using = SegmentAttributeXYDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java index 05bf3e958..685cb5c21 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class SegmentAttributeXYDeserializer extends EnumeratedDeserializer { SegmentAttributeXYDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java index c49e2831c..59ba04c61 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYList.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class SegmentAttributeXYList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java index 197276af0..44a56038e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SegmentAttributeXYSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class SegmentAttributeXYSerializer extends EnumeratedSerializer { SegmentAttributeXYSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java index d9afbcc34..26a3907d9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitList.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class SpeedLimitList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java index 41c14c7fb..2d78ff819 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitType.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = SpeedLimitTypeSerializer.class) @JsonDeserialize(using = SpeedLimitTypeDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java index e05b38fdd..f7bcb8f59 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class SpeedLimitTypeDeserializer extends EnumeratedDeserializer { SpeedLimitTypeDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java index 42ca329a9..902011806 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/SpeedLimitTypeSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class SpeedLimitTypeSerializer extends EnumeratedSerializer { SpeedLimitTypeSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java index 4a056a83e..bf1cb2bcf 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/common/Velocity.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.common; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.common; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Velocity.VelocityDeserializer.class) public class Velocity extends Asn1Integer { public Velocity() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java index 13fe811df..44835164e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Circle.java @@ -1,51 +1,51 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Circle extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "center") + @JsonProperty("center") private Position3D center; - @Asn1Property(tag = 1) - @JsonDeserialize(using = Radius_B12.Radius_B12Deserializer.class) + @Asn1Property(tag = 1, name = "radius") + @JsonProperty("radius") private Radius_B12 radius; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "units") + @JsonProperty("units") private DistanceUnits units; Circle() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java index da671f402..902b5e200 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUse.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = DirectionOfUseSerializer.class) @JsonDeserialize(using = DirectionOfUseDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java index 0c5b4c673..f4c534505 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class DirectionOfUseDeserializer extends EnumeratedDeserializer { DirectionOfUseDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java index 17b71f89c..2dfb054c4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DirectionOfUseSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class DirectionOfUseSerializer extends EnumeratedSerializer { DirectionOfUseSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java index 7de461351..e68c69632 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnits.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = DistanceUnitsSerializer.class) @JsonDeserialize(using = DistanceUnitsDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java index 62c5e9233..d516cef3a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class DistanceUnitsDeserializer extends EnumeratedDeserializer { DistanceUnitsDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java index d0d7c9848..7fdcc3f1e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/DistanceUnitsSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class DistanceUnitsSerializer extends EnumeratedSerializer { DistanceUnitsSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java index 28b0db664..3077251ad 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitService.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class ExitService extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java index e45be02f8..ee43415f2 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ExitServiceSequence.java @@ -1,70 +1,62 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class ExitServiceSequence extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "item") + @JsonProperty("item") private ItemChoice item; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + @Asn1Property(tag = 0, name = "itis") + @JsonProperty("itis") private ITIScodes itis; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "text") + @JsonProperty("text") private ITIStextPhrase text; ItemChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } ExitServiceSequence() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java index 48d2230ab..f4138128b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignage.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class GenericSignage extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java index 8c9c20877..d795ed5fd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GenericSignageSequence.java @@ -1,70 +1,62 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class GenericSignageSequence extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "item") + @JsonProperty("item") private ItemChoice item; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + @Asn1Property(tag = 0, name = "itis") + @JsonProperty("itis") private ITIScodes itis; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "text") + @JsonProperty("text") private ITIStextPhrase text; ItemChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } GenericSignageSequence() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java index 4251898bd..3c0e9ebeb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeographicalPath.java @@ -1,91 +1,92 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.j2735.common.*; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.*; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_GeographicalPath; import us.dot.its.jpo.ode.plugin.types.Asn1Boolean; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_GeographicalPath; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class GeographicalPath extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) + @Asn1Property(tag = 0, name = "name", optional = true) + @JsonProperty("name") private DescriptiveName name; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "id", optional = true) + @JsonProperty("id") private RoadSegmentReferenceID id; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "anchor", optional = true) + @JsonProperty("anchor") private Position3D anchor; - @Asn1Property(tag = 3, optional = true) - @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + @Asn1Property(tag = 3, name = "laneWidth", optional = true) + @JsonProperty("laneWidth") private LaneWidth laneWidth; - @Asn1Property(tag = 4, optional = true) + @Asn1Property(tag = 4, name = "directionality", optional = true) + @JsonProperty("directionality") private DirectionOfUse directionality; - @Asn1Property(tag = 5, optional = true) + @Asn1Property(tag = 5, name = "closedPath", optional = true) + @JsonProperty("closedPath") private Asn1Boolean closedPath; - @Asn1Property(tag = 6, optional = true) + @Asn1Property(tag = 6, name = "direction", optional = true) + @JsonProperty("direction") private HeadingSlice direction; - @Asn1Property(tag = 7, optional = true) + @Asn1Property(tag = 7, name = "description", optional = true) + @JsonProperty("description") private DescriptionChoice description; - @Asn1Property(tag = 8, optional = true) + @Asn1Property(tag = 8, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class DescriptionChoice extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "path") + @JsonProperty("path") private OffsetSystem path; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "geometry") + @JsonProperty("geometry") private GeometricProjection geometry; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "oldRegion") + @JsonProperty("oldRegion") private ValidRegion oldRegion; DescriptionChoice() { super(true); } - - @Override - protected List> listTypes() { - return null; - } } @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java index d1d76f883..4b7aae252 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/GeometricProjection.java @@ -1,59 +1,61 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.j2735.common.Extent; -import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; -import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.Extent; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; import us.dot.its.jpo.ode.plugin.j2735.region.Reg_GeometricProjection; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class GeometricProjection extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "direction") + @JsonProperty("direction") private HeadingSlice direction; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "extent", optional = true) + @JsonProperty("extent") private Extent extent; - @Asn1Property(tag = 2, optional = true) - @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + @Asn1Property(tag = 2, name = "laneWidth", optional = true) + @JsonProperty("laneWidth") private LaneWidth laneWidth; - @Asn1Property(tag = 3) + @Asn1Property(tag = 3, name = "circle") + @JsonProperty("circle") private Circle circle; - @Asn1Property(tag = 4, optional = true) + @Asn1Property(tag = 4, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java index 8dc8a0631..db066f0c9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ITIStextPhrase.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.IA5String; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.types.IA5String; + public class ITIStextPhrase extends IA5String { public ITIStextPhrase() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java index 66947881e..f14d62179 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCode.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = MUTCDCodeSerializer.class) @JsonDeserialize(using = MUTCDCodeDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java index a699b83e2..31f24e527 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class MUTCDCodeDeserializer extends EnumeratedDeserializer { MUTCDCodeDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java index cd570d7cc..d9418e9ad 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MUTCDCodeSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class MUTCDCodeSerializer extends EnumeratedSerializer { MUTCDCodeSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java index 5a8b5a919..ea4e0e390 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MinutesDuration.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) public class MinutesDuration extends Asn1Integer { public MinutesDuration() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java index 44dcfdb01..54d976060 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/MsgCRC.java @@ -1,44 +1,38 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ -public class MsgCRC extends Asn1OctetString { + *============================================================================*/ - private String value; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; + +public class MsgCRC extends Asn1OctetString { + + @JsonValue public String getValue() { return value; } - public void setValue(String value) { - this.value = value; - } - @Override public String toString() { return value; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java index cb089e5f6..02f729046 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLL.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = NodeAttributeLLSerializer.class) @JsonDeserialize(using = NodeAttributeLLDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java index 327ba21d1..7621e8150 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class NodeAttributeLLDeserializer extends EnumeratedDeserializer { NodeAttributeLLDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java index 8772cad1b..f8a63b584 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLList.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class NodeAttributeLLList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java index 1d74fa8dc..508fcb134 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeLLSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class NodeAttributeLLSerializer extends EnumeratedSerializer { NodeAttributeLLSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java index 37ca7cf0d..405183c27 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLL.java @@ -1,73 +1,73 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.common.LaneDataAttributeList; -import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneDataAttributeList; +import us.dot.its.jpo.ode.plugin.j2735.common.Offset_B10; import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeAttributeSetLL; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -/** - * - * EDITED: Add @JsonProperty annotations to dWidth and dElevation - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class NodeAttributeSetLL extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) + @Asn1Property(tag = 0, name = "localNode", optional = true) + @JsonProperty("localNode") @JsonDeserialize(using = NodeAttributeLLList.NodeAttributeLLListDeserializer.class) private NodeAttributeLLList localNode; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "disabled", optional = true) + @JsonProperty("disabled") @JsonDeserialize(using = SegmentAttributeLLList.SegmentAttributeLLListDeserializer.class) private SegmentAttributeLLList disabled; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "enabled", optional = true) + @JsonProperty("enabled") @JsonDeserialize(using = SegmentAttributeLLList.SegmentAttributeLLListDeserializer.class) private SegmentAttributeLLList enabled; - @Asn1Property(tag = 3, optional = true) - @JacksonXmlElementWrapper(useWrapping = false) + @Asn1Property(tag = 3, name = "data", optional = true) + @JsonProperty("data") + @JsonSerialize(using = LaneDataAttributeList.LaneDataAttributeListSerializer.class) + @JsonDeserialize(using = LaneDataAttributeList.LaneDataAttributeListDeserializer.class) private LaneDataAttributeList data; - @Asn1Property(tag = 4, optional = true) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 4, name = "dWidth", optional = true) @JsonProperty("dWidth") private Offset_B10 dWidth; - @Asn1Property(tag = 5, optional = true) - @JsonDeserialize(using = Offset_B10.Offset_B10Deserializer.class) + @Asn1Property(tag = 5, name = "dElevation", optional = true) @JsonProperty("dElevation") private Offset_B10 dElevation; - @Asn1Property(tag = 6, optional = true) + @Asn1Property(tag = 6, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @JsonInclude(Include.NON_NULL) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java index 17596168e..7247ae614 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeLL.java @@ -1,46 +1,47 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class NodeLL extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "delta") + @JsonProperty("delta") private NodeOffsetPointLL delta; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "attributes", optional = true) + @JsonProperty("attributes") private NodeAttributeSetLL attributes; NodeLL() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java index f16e9cb93..c5f98d200 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeListLL.java @@ -1,47 +1,44 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; + @Getter @Setter @JsonInclude(Include.NON_NULL) public class NodeListLL extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "nodes") + @JsonProperty("nodes") @JacksonXmlElementWrapper(localName = "nodes") @JacksonXmlProperty(localName = "NodeLL") private NodeSetLL nodes; @@ -49,9 +46,4 @@ public class NodeListLL extends Asn1Choice { NodeListLL() { super(true); } - - @Override - protected List> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java index c0caf658f..c3f131082 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeOffsetPointLL.java @@ -1,42 +1,37 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.Node_LLmD_64b; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.annotation.JsonProperty; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointLL; -import java.util.Optional; -import java.util.List; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.Node_LLmD_64b; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_NodeOffsetPointLL; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; + @Getter @Setter @JsonInclude(Include.NON_NULL) @@ -63,15 +58,11 @@ public class NodeOffsetPointLL extends Asn1Choice { @Asn1Property(tag = 6, name = "node-LatLon") @JsonProperty("node-LatLon") private Node_LLmD_64b node_LatLon; - @Asn1Property(tag = 7) + @Asn1Property(tag = 7, name = "regional") + @JsonProperty("regional") private Reg_NodeOffsetPointLL regional; NodeOffsetPointLL() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java index aafce72c7..beb77e1fc 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeSetLL.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class NodeSetLL extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java index 574f7165f..d18ddfbce 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_24B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B12; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B12; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_24B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B12 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B12.OffsetLL_B12Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B12 lat; Node_LL_24B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java index 065861345..eb8294ef1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_28B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B14; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B14; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_28B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B14 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B14.OffsetLL_B14Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B14 lat; Node_LL_28B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java index b1f6274ba..8d128491a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_32B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_32B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B16 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B16 lat; Node_LL_32B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java index 625fd2dc7..439cf372f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_36B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B18; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B18; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_36B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B18 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B18.OffsetLL_B18Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B18 lat; Node_LL_36B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java index 40499b07e..571ca2a98 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_44B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B22; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B22; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_44B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B22 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B22.OffsetLL_B22Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B22 lat; Node_LL_44B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java index 0e906159f..b93dec8cd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Node_LL_48B.java @@ -1,50 +1,48 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B24; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B24; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class Node_LL_48B extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) + @Asn1Property(tag = 0, name = "lon") + @JsonProperty("lon") private OffsetLL_B24 lon; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B24.OffsetLL_B24Deserializer.class) + @Asn1Property(tag = 1, name = "lat") + @JsonProperty("lat") private OffsetLL_B24 lat; Node_LL_48B() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java index aac5dc2af..ded65d7f4 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/OffsetSystem.java @@ -1,72 +1,65 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class OffsetSystem extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) - @JsonDeserialize(using = Zoom.ZoomDeserializer.class) + @Asn1Property(tag = 0, name = "scale", optional = true) + @JsonProperty("scale") private Zoom scale; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "offset") + @JsonProperty("offset") private OffsetChoice offset; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class OffsetChoice extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "xy") + @JsonProperty("xy") private NodeListXY xy; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "ll") + @JsonProperty("ll") private NodeListLL ll; OffsetChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } OffsetSystem() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java index c4de7e997..5d75071dd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Radius_B12.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Radius_B12.Radius_B12Deserializer.class) public class Radius_B12 extends Asn1Integer { public Radius_B12() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java index 963ea6bf2..d74e70b05 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionList.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class RegionList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java index ad689e04b..f4f392fd6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionOffsets.java @@ -1,53 +1,51 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.OffsetLL_B16; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class RegionOffsets extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + @Asn1Property(tag = 0, name = "xOffset") + @JsonProperty("xOffset") private OffsetLL_B16 xOffset; - @Asn1Property(tag = 1) - @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + @Asn1Property(tag = 1, name = "yOffset") + @JsonProperty("yOffset") private OffsetLL_B16 yOffset; - @Asn1Property(tag = 2, optional = true) - @JsonDeserialize(using = OffsetLL_B16.OffsetLL_B16Deserializer.class) + @Asn1Property(tag = 2, name = "zOffset", optional = true) + @JsonProperty("zOffset") private OffsetLL_B16 zOffset; RegionOffsets() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java index 613faf01e..ad261e6bb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RegionPointSet.java @@ -1,53 +1,53 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class RegionPointSet extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) + @Asn1Property(tag = 0, name = "anchor", optional = true) + @JsonProperty("anchor") private Position3D anchor; - @Asn1Property(tag = 1, optional = true) - @JsonDeserialize(using = Zoom.ZoomDeserializer.class) + @Asn1Property(tag = 1, name = "scale", optional = true) + @JsonProperty("scale") private Zoom scale; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "nodeList") + @JsonProperty("nodeList") @JacksonXmlElementWrapper(localName = "nodeList") @JacksonXmlProperty(localName = "RegionOffsets") private RegionList nodeList; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java index fcdf96ac2..bf8582829 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/RoadSignID.java @@ -1,52 +1,55 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; -import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class RoadSignID extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "position") + @JsonProperty("position") private Position3D position; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "viewAngle") + @JsonProperty("viewAngle") private HeadingSlice viewAngle; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "mutcdCode", optional = true) + @JsonProperty("mutcdCode") private MUTCDCode mutcdCode; - @Asn1Property(tag = 3, optional = true) + @Asn1Property(tag = 3, name = "crc", optional = true) + @JsonProperty("crc") private MsgCRC crc; RoadSignID() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java index e8e0827e5..cd1cb6fbd 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLL.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = SegmentAttributeLLSerializer.class) @JsonDeserialize(using = SegmentAttributeLLDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java index 1a765b7d7..e301cda4a 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class SegmentAttributeLLDeserializer extends EnumeratedDeserializer { SegmentAttributeLLDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java index 4b0b2b36d..9736b4f0d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLList.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.serialization.SequenceOfEnumeratedDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class SegmentAttributeLLList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java index ec5a9f31b..8c933cc0c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SegmentAttributeLLSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class SegmentAttributeLLSerializer extends EnumeratedSerializer { SegmentAttributeLLSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java index e2bb76be4..f0852af82 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ShapePointSet.java @@ -1,55 +1,56 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; -import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; -import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.LaneWidth; +import us.dot.its.jpo.ode.plugin.j2735.common.NodeListXY; +import us.dot.its.jpo.ode.plugin.j2735.common.Position3D; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class ShapePointSet extends Asn1Sequence { - @Asn1Property(tag = 0, optional = true) + @Asn1Property(tag = 0, name = "anchor", optional = true) + @JsonProperty("anchor") private Position3D anchor; - @Asn1Property(tag = 1, optional = true) - @JsonDeserialize(using = LaneWidth.LaneWidthDeserializer.class) + @Asn1Property(tag = 1, name = "laneWidth", optional = true) + @JsonProperty("laneWidth") private LaneWidth laneWidth; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "directionality", optional = true) + @JsonProperty("directionality") private DirectionOfUse directionality; - @Asn1Property(tag = 3) + @Asn1Property(tag = 3, name = "nodeList") + @JsonProperty("nodeList") private NodeListXY nodeList; ShapePointSet() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java index a3335e2fe..69fdf27c8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SignPrority.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) public class SignPrority extends Asn1Integer { public SignPrority() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java index 840dc1a0f..b7d83248c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimit.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class SpeedLimit extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java index 382e88f2e..427028322 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/SpeedLimitSequence.java @@ -1,70 +1,62 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class SpeedLimitSequence extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "item") + @JsonProperty("item") private ItemChoice item; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + @Asn1Property(tag = 0, name = "itis") + @JsonProperty("itis") private ITIScodes itis; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "text") + @JsonProperty("text") private ITIStextPhrase text; ItemChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } SpeedLimitSequence() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java index b109ee671..442e9a683 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java @@ -1,113 +1,111 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.j2735.common.DYear; -import us.dot.its.jpo.ode.plugin.j2735.common.FurtherInfoID; -import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; -import us.dot.its.jpo.ode.plugin.j2735.common.SSPindex; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import us.dot.its.jpo.ode.plugin.j2735.common.DYear; +import us.dot.its.jpo.ode.plugin.j2735.common.FurtherInfoID; +import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; +import us.dot.its.jpo.ode.plugin.j2735.common.SSPindex; import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodesAndText; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; /* * EDITED -> notUsed, notUsed1, notUsed2, notUsed3, durationTime fields. */ -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class TravelerDataFrame extends Asn1Sequence { - @Asn1Property(tag = 0) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + @Asn1Property(tag = 0, name = "notUsed") + @JsonProperty("notUsed") private SSPindex notUsed; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "frameType") + @JsonProperty("frameType") private TravelerInfoType frameType; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "msgId") + @JsonProperty("msgId") private MsgIdChoice msgId; - @Asn1Property(tag = 3, optional = true) - @JsonDeserialize(using = DYear.DYearDeserializer.class) + @Asn1Property(tag = 3, name = "startYear", optional = true) + @JsonProperty("startYear") private DYear startYear; - @Asn1Property(tag = 4) - @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + @Asn1Property(tag = 4, name = "startTime") + @JsonProperty("startTime") private MinuteOfTheYear startTime; - @Asn1Property(tag = 5) - @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) + @Asn1Property(tag = 5, name = "durationTime") + @JsonProperty("durationTime") private MinutesDuration durationTime; - @Asn1Property(tag = 6) - @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) + @Asn1Property(tag = 6, name = "priority") + @JsonProperty("priority") private SignPrority priority; - @Asn1Property(tag = 7) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + @Asn1Property(tag = 7, name = "notUsed1") + @JsonProperty("notUsed1") private SSPindex notUsed1; - @Asn1Property(tag = 8) + @Asn1Property(tag = 8, name = "regions") + @JsonProperty("regions") private SequenceOfRegions regions; - @Asn1Property(tag = 9) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + @Asn1Property(tag = 9, name = "notUsed2") + @JsonProperty("notUsed2") private SSPindex notUsed2; - @Asn1Property(tag = 10) - @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + @Asn1Property(tag = 10, name = "notUsed3") + @JsonProperty("notUsed3") private SSPindex notUsed3; - @Asn1Property(tag = 11) + @Asn1Property(tag = 11, name = "content") + @JsonProperty("content") private ContentChoice content; - @Asn1Property(tag = 12, optional = true) + @Asn1Property(tag = 12, name = "url", optional = true) + @JsonProperty("url") private URL_Short url; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class MsgIdChoice extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "furtherInfoID") + @JsonProperty("furtherInfoID") private FurtherInfoID furtherInfoID; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "roadSignID") + @JsonProperty("roadSignID") private RoadSignID roadSignID; MsgIdChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } @JsonInclude(Include.NON_NULL) @@ -121,23 +119,28 @@ public static class SequenceOfRegions extends Asn1SequenceOf { @Setter @JsonInclude(Include.NON_NULL) public static class ContentChoice extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "advisory") + @JsonProperty("advisory") @JsonDeserialize(using = AdvisoryDeserializer.class) @JsonSerialize(using = AdvisorySerializer.class) private ITIScodesAndText advisory; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "workZone") + @JsonProperty("workZone") @JsonDeserialize(using = WorkZoneDeserializer.class) @JsonSerialize(using = WorkZoneSerializer.class) private WorkZone workZone; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "genericSign") + @JsonProperty("genericSign") @JsonDeserialize(using = GenericSignDeserializer.class) @JsonSerialize(using = GenericSignSerializer.class) private GenericSignage genericSign; - @Asn1Property(tag = 3) + @Asn1Property(tag = 3, name = "speedLimit") + @JsonProperty("speedLimit") @JsonDeserialize(using = SpeedLimitDeserializer.class) @JsonSerialize(using = SpeedLimitSerializer.class) private SpeedLimit speedLimit; - @Asn1Property(tag = 4) + @Asn1Property(tag = 4, name = "exitService") + @JsonProperty("exitService") @JsonDeserialize(using = ExitServiceDeserializer.class) @JsonSerialize(using = ExitServiceSerializer.class) private ExitService exitService; @@ -145,11 +148,6 @@ public static class ContentChoice extends Asn1Choice { ContentChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } TravelerDataFrame() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java.bak b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java.bak new file mode 100644 index 000000000..b109ee671 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrame.java.bak @@ -0,0 +1,218 @@ +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.j2735.common.DYear; +import us.dot.its.jpo.ode.plugin.j2735.common.FurtherInfoID; +import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; +import us.dot.its.jpo.ode.plugin.j2735.common.SSPindex; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import java.util.List; +import java.util.Optional; +import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodesAndText; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfDeserializer; +import us.dot.its.jpo.ode.plugin.serialization.NestedSequenceOfSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/* + * EDITED -> notUsed, notUsed1, notUsed2, notUsed3, durationTime fields. + */ + +/** + * + ******************************************************************************* + * + * This source file was generated by a tool. Beware manual edits might be + * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * + ******************************************************************************* + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + ****************************************************************************** + * + */ +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +@Getter +@Setter +public class TravelerDataFrame extends Asn1Sequence { + + @Asn1Property(tag = 0) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed; + @Asn1Property(tag = 1) + private TravelerInfoType frameType; + @Asn1Property(tag = 2) + private MsgIdChoice msgId; + @Asn1Property(tag = 3, optional = true) + @JsonDeserialize(using = DYear.DYearDeserializer.class) + private DYear startYear; + @Asn1Property(tag = 4) + @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + private MinuteOfTheYear startTime; + @Asn1Property(tag = 5) + @JsonDeserialize(using = MinutesDuration.MinutesDurationDeserializer.class) + private MinutesDuration durationTime; + @Asn1Property(tag = 6) + @JsonDeserialize(using = SignPrority.SignProrityDeserializer.class) + private SignPrority priority; + @Asn1Property(tag = 7) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed1; + @Asn1Property(tag = 8) + private SequenceOfRegions regions; + @Asn1Property(tag = 9) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed2; + @Asn1Property(tag = 10) + @JsonDeserialize(using = SSPindex.SSPindexDeserializer.class) + private SSPindex notUsed3; + @Asn1Property(tag = 11) + private ContentChoice content; + @Asn1Property(tag = 12, optional = true) + private URL_Short url; + + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + public static class MsgIdChoice extends Asn1Choice { + @Asn1Property(tag = 0) + private FurtherInfoID furtherInfoID; + @Asn1Property(tag = 1) + private RoadSignID roadSignID; + + MsgIdChoice() { + super(false); + } + + @Override + protected List> listTypes() { + return null; + } + } + + @JsonInclude(Include.NON_NULL) + public static class SequenceOfRegions extends Asn1SequenceOf { + SequenceOfRegions() { + super(GeographicalPath.class, 1L, 16L); + } + } + + @Getter + @Setter + @JsonInclude(Include.NON_NULL) + public static class ContentChoice extends Asn1Choice { + @Asn1Property(tag = 0) + @JsonDeserialize(using = AdvisoryDeserializer.class) + @JsonSerialize(using = AdvisorySerializer.class) + private ITIScodesAndText advisory; + @Asn1Property(tag = 1) + @JsonDeserialize(using = WorkZoneDeserializer.class) + @JsonSerialize(using = WorkZoneSerializer.class) + private WorkZone workZone; + @Asn1Property(tag = 2) + @JsonDeserialize(using = GenericSignDeserializer.class) + @JsonSerialize(using = GenericSignSerializer.class) + private GenericSignage genericSign; + @Asn1Property(tag = 3) + @JsonDeserialize(using = SpeedLimitDeserializer.class) + @JsonSerialize(using = SpeedLimitSerializer.class) + private SpeedLimit speedLimit; + @Asn1Property(tag = 4) + @JsonDeserialize(using = ExitServiceDeserializer.class) + @JsonSerialize(using = ExitServiceSerializer.class) + private ExitService exitService; + + ContentChoice() { + super(false); + } + + @Override + protected List> listTypes() { + return null; + } + } + + TravelerDataFrame() { + super(true); + } + + public static class AdvisoryDeserializer extends NestedSequenceOfDeserializer { + public AdvisoryDeserializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class AdvisorySerializer extends NestedSequenceOfSerializer { + public AdvisorySerializer() { + super(ITIScodesAndText.class, "SEQUENCE"); + } + } + + public static class WorkZoneDeserializer extends NestedSequenceOfDeserializer { + public WorkZoneDeserializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class WorkZoneSerializer extends NestedSequenceOfSerializer { + public WorkZoneSerializer() { + super(WorkZone.class, "SEQUENCE"); + } + } + + public static class GenericSignDeserializer extends NestedSequenceOfDeserializer { + public GenericSignDeserializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class GenericSignSerializer extends NestedSequenceOfSerializer { + public GenericSignSerializer() { + super(GenericSignage.class, "SEQUENCE"); + } + } + + public static class SpeedLimitDeserializer extends NestedSequenceOfDeserializer { + public SpeedLimitDeserializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class SpeedLimitSerializer extends NestedSequenceOfSerializer { + public SpeedLimitSerializer() { + super(SpeedLimit.class, "SEQUENCE"); + } + } + + public static class ExitServiceDeserializer extends NestedSequenceOfDeserializer { + public ExitServiceDeserializer() { + super(ExitService.class, "SEQUENCE"); + } + } + + public static class ExitServiceSerializer extends NestedSequenceOfSerializer { + public ExitServiceSerializer() { + super(ExitService.class, "SEQUENCE"); + } + } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java index 0842e5c0b..c2e61d33e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerDataFrameList.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class TravelerDataFrameList extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java index 60b430f05..98b67f24e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoType.java @@ -1,34 +1,32 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import lombok.Getter; -import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import lombok.Getter; +import us.dot.its.jpo.ode.plugin.types.Asn1Enumerated; + @Getter @JsonSerialize(using = TravelerInfoTypeSerializer.class) @JsonDeserialize(using = TravelerInfoTypeDeserializer.class) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java index cbd2b76b9..a3ee44c96 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeDeserializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedDeserializer; + public class TravelerInfoTypeDeserializer extends EnumeratedDeserializer { TravelerInfoTypeDeserializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java index 4b59b649a..f12fca3eb 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInfoTypeSerializer.java @@ -1,31 +1,29 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import us.dot.its.jpo.ode.plugin.serialization.EnumeratedSerializer; + public class TravelerInfoTypeSerializer extends EnumeratedSerializer { TravelerInfoTypeSerializer() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java index acc409ab7..3c87e3e17 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/TravelerInformation.java @@ -1,69 +1,71 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; +import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import us.dot.its.jpo.ode.plugin.j2735.region.Reg_TravelerInformation; +import us.dot.its.jpo.ode.plugin.asn1.Asn1Object; import us.dot.its.jpo.ode.plugin.j2735.common.MinuteOfTheYear; import us.dot.its.jpo.ode.plugin.j2735.common.MsgCount; +import us.dot.its.jpo.ode.plugin.j2735.region.Reg_TravelerInformation; import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; -import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; /* - * EDITED - Changed base class to Asn1Object + * EDITED - Changed base class to Asn1Object, removed call to super constructor. */ -/** - * EDITED - Change base class to Asn1Object - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class TravelerInformation extends Asn1Object { - @Asn1Property(tag = 0) - @JsonDeserialize(using = MsgCount.MsgCountDeserializer.class) + @Asn1Property(tag = 0, name = "msgCnt") + @JsonProperty("msgCnt") private MsgCount msgCnt; - @Asn1Property(tag = 1, optional = true) - @JsonDeserialize(using = MinuteOfTheYear.MinuteOfTheYearDeserializer.class) + @Asn1Property(tag = 1, name = "timeStamp", optional = true) + @JsonProperty("timeStamp") private MinuteOfTheYear timeStamp; - @Asn1Property(tag = 2, optional = true) + @Asn1Property(tag = 2, name = "packetID", optional = true) + @JsonProperty("packetID") private UniqueMSGID packetID; - @Asn1Property(tag = 3, optional = true) + @Asn1Property(tag = 3, name = "urlB", optional = true) + @JsonProperty("urlB") private URL_Base urlB; - @Asn1Property(tag = 4) + @Asn1Property(tag = 4, name = "dataFrames") + @JsonProperty("dataFrames") @JacksonXmlElementWrapper(localName = "dataFrames") @JacksonXmlProperty(localName = "TravelerDataFrame") private TravelerDataFrameList dataFrames; - @Asn1Property(tag = 5, optional = true) + @Asn1Property(tag = 5, name = "regional", optional = true) + @JsonProperty("regional") private SequenceOfRegional regional; @JsonInclude(Include.NON_NULL) @@ -73,7 +75,5 @@ public static class SequenceOfRegional extends Asn1SequenceOf { + SequenceOfRegional() { + super(Reg_TravelerInformation.class, 1L, 4L); + } + } + +// TravelerInformation() { +// super(true); +// } +} \ No newline at end of file diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java index 0d0bb8e67..f04bade78 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Base.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.IA5String; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.types.IA5String; + public class URL_Base extends IA5String { public URL_Base() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java index 11e75d3a6..05c0d6ce3 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/URL_Short.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.IA5String; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.types.IA5String; + public class URL_Short extends IA5String { public URL_Short() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java index 5bce94e6b..c894f2f21 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/UniqueMSGID.java @@ -1,44 +1,38 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ -public class UniqueMSGID extends Asn1OctetString { + *============================================================================*/ - private String value; +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import us.dot.its.jpo.ode.plugin.types.Asn1OctetString; + +public class UniqueMSGID extends Asn1OctetString { + + @JsonValue public String getValue() { return value; } - public void setValue(String value) { - this.value = value; - } - @Override public String toString() { return value; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java index e331f99e2..477b4c4c0 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/ValidRegion.java @@ -1,75 +1,72 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; -import us.dot.its.jpo.ode.plugin.j2735.common.Extent; -import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.common.Extent; +import us.dot.its.jpo.ode.plugin.j2735.common.HeadingSlice; import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class ValidRegion extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "direction") + @JsonProperty("direction") private HeadingSlice direction; - @Asn1Property(tag = 1, optional = true) + @Asn1Property(tag = 1, name = "extent", optional = true) + @JsonProperty("extent") private Extent extent; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "area") + @JsonProperty("area") private AreaChoice area; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class AreaChoice extends Asn1Choice { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "shapePointSet") + @JsonProperty("shapePointSet") private ShapePointSet shapePointSet; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "circle") + @JsonProperty("circle") private Circle circle; - @Asn1Property(tag = 2) + @Asn1Property(tag = 2, name = "regionPointSet") + @JsonProperty("regionPointSet") private RegionPointSet regionPointSet; AreaChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } ValidRegion() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java index c561e4e04..8feaeda66 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZone.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class WorkZone extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java index da8de75fe..9bbf80a9b 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/WorkZoneSequence.java @@ -1,70 +1,62 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.j2735.itis.ITIScodes; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class WorkZoneSequence extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "item") + @JsonProperty("item") private ItemChoice item; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + @Asn1Property(tag = 0, name = "itis") + @JsonProperty("itis") private ITIScodes itis; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "text") + @JsonProperty("text") private ITIStextPhrase text; ItemChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } WorkZoneSequence() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java index 178ebad5b..60c53f968 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/Zoom.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.travelerinformation; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = Zoom.ZoomDeserializer.class) public class Zoom extends Asn1Integer { public Zoom() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java index 72b4639d5..1f1c2afb6 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/IntegerDeserializer.java @@ -29,11 +29,9 @@ protected IntegerDeserializer(Class vc) { } @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException, JacksonException { - T result = null; + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { + T result = construct(); if (jsonParser instanceof FromXmlParser xmlParser) { - result = construct(); TreeNode node = xmlParser.getCodec().readTree(xmlParser); if (node instanceof NumericNode numNode) { result.setValue(numNode.longValue()); @@ -44,7 +42,7 @@ public T deserialize(JsonParser jsonParser, DeserializationContext deserializati result.setValue(value); } } else { - result = jsonParser.getCodec().readValue(jsonParser, thisClass); + result.setValue(jsonParser.readValueAs(Long.class)); } return result; } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java index dbae0a082..0b1858a27 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/OpenTypeDeserializer.java @@ -12,6 +12,8 @@ import java.io.IOException; import us.dot.its.jpo.ode.plugin.types.Asn1Type; +import static us.dot.its.jpo.ode.plugin.utils.XmlUtils.*; + /** * See description in {@link OpenTypeSerializer}. * @@ -29,28 +31,18 @@ protected OpenTypeDeserializer(Class vc, String wrapped) { } @Override - public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) - throws IOException, JacksonException { + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JacksonException { T result = null; if (jsonParser instanceof FromXmlParser xmlParser) { - XmlMapper xmlMapper = (XmlMapper) xmlParser.getCodec(); + // XML: Unwrap + XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); TreeNode node = xmlParser.getCodec().readTree(xmlParser); - if (node instanceof ObjectNode objectNode) { - JsonNode unwrapped = objectNode.findValue(wrapped); - - // HACK: serialization annotations are ignored here. - // ideally we would like to just unwrap the original literal xml and pass it - // through - // but Jackson's XML parser insists on converting everything to JSON, so the - // original XML is - // not preserved. Specifically, empty elements like are expanded to - // , - // but the boolean and enumerated deserializers can still handle this. - String unwrappedXml = xmlMapper.writeValueAsString(unwrapped); - - result = xmlMapper.readValue(unwrappedXml, thisClass); - } + String xml = xmlMapper.writeValueAsString(node); + var tokens = tokenize(xml); + var unwrapped = unwrap(tokens); + result = xmlMapper.readValue(stringifyTokens(unwrapped), thisClass); } else { + // JSON: pass through result = jsonParser.getCodec().readValue(jsonParser, thisClass); } return result; diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceDeserializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceDeserializer.java new file mode 100644 index 000000000..cb3a1b618 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceDeserializer.java @@ -0,0 +1,64 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import static us.dot.its.jpo.ode.plugin.utils.XmlUtils.*; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.fasterxml.jackson.dataformat.xml.deser.FromXmlParser; +import java.io.IOException; +import lombok.SneakyThrows; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + +/** + * Deserializer for SEQUENCE-OF CHOICE types. + * These are unwrapped in XER, but wrapped in JER. + * @param The Asn1Choice type + * @param The Asn1SequenceOf type + */ +public abstract class SequenceOfChoiceDeserializer> + extends StdDeserializer { + + protected final Class choiceClass; + protected final Class sequenceOfClass; + + protected abstract T construct(); + + protected SequenceOfChoiceDeserializer(Class choiceClass, Class sequenceOfClass) { + super(sequenceOfClass); + this.choiceClass = choiceClass; + this.sequenceOfClass = sequenceOfClass; + } + + @SneakyThrows + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + T result = construct(); + if (jsonParser instanceof FromXmlParser xmlParser) { + // XML: expects unwrapped choice items + // unwrap and deserialize each choice item + XmlMapper xmlMapper = (XmlMapper)xmlParser.getCodec(); + TreeNode node = xmlMapper.readTree(xmlParser); + String xml = xmlMapper.writeValueAsString(node); + var tokens = tokenize(xml); + var unwrapped = unwrap(tokens); + var grouped = groupTopLevelTokens(unwrapped); + for (var group : grouped) { + var wrappedGroup = wrap(group, choiceClass.getSimpleName()); + S choice = xmlMapper.readValue(stringifyTokens(wrappedGroup), choiceClass); + result.add(choice); + } + } else { + // JSON: expects wrapped choice items, pass through as normal + result = jsonParser.getCodec().readValue(jsonParser, sequenceOfClass); + } + return result; + } + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceSerializer.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceSerializer.java new file mode 100644 index 000000000..29c6077a5 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/serialization/SequenceOfChoiceSerializer.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.plugin.serialization; + +import static us.dot.its.jpo.ode.plugin.utils.XmlUtils.*; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; +import com.fasterxml.jackson.dataformat.xml.ser.XmlSerializerProvider; +import java.io.IOException; +import lombok.SneakyThrows; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + +/** + * Serializer for SEQUENCE-OF CHOICE types. + * These are unwrapped in XER, but wrapped in JER. + * @param The Asn1Choice type + * @param The Asn1SequenceOf type + */ +public class SequenceOfChoiceSerializer> + extends StdSerializer { + + protected final Class choiceClass; + protected final Class sequenceOfClass; + + protected SequenceOfChoiceSerializer(Class choiceClass, Class sequenceOfClass) { + super(sequenceOfClass); + this.choiceClass = choiceClass; + this.sequenceOfClass = sequenceOfClass; + } + + @SneakyThrows + @Override + public void serialize(T sequenceOf, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { + if (serializerProvider instanceof XmlSerializerProvider xmlProvider) { + // XER: Choice items not wrapped + var xmlGen = (ToXmlGenerator)jsonGenerator; + var mapper = SerializationUtil.xmlMapper(); + + for (var choiceItem : sequenceOf) { + String choiceXml = mapper.writeValueAsString(choiceItem); + String unwrappedXml = stringifyTokens(unwrap(tokenize(choiceXml))); + xmlGen.writeRaw(unwrappedXml); + } + + } else { + // JER: Normal, choice items are wrapped + jsonGenerator.writeObject(sequenceOf); + } + } + + +} diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java index a9fab258d..531d6380d 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1Choice.java @@ -3,8 +3,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import java.util.List; -import java.util.Optional; import us.dot.its.jpo.ode.plugin.serialization.SerializationUtil; /** @@ -19,36 +17,6 @@ public Asn1Choice(boolean hasExtensionMarker) { this.hasExtensionMarker = hasExtensionMarker; } - /** - * Validates if one and only one option is selected for the choice. - */ - protected boolean isValid() { - var types = listTypes(); - long numChosen = types.stream().filter(Optional::isPresent).count(); - return numChosen == 1; - } - - /** - * Ref ITU-T X.691 (02/2021) Section 23. - * - * @return the index of the chosen alternative - */ - protected int chosenIndex() { - List> types = listTypes(); - for (int i = 0; i < types.size(); i++) { - if (types.get(i).isPresent()) { - return i; - } - } - return -1; - } - - protected int maxIndex() { - return listTypes().size() - 1; - } - - protected abstract List> listTypes(); - @Override public String toString() { ObjectMapper mapper = SerializationUtil.jsonMapper(); diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java index 927eff5af..e2f21e537 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/types/Asn1OctetString.java @@ -1,12 +1,31 @@ package us.dot.its.jpo.ode.plugin.types; +import com.fasterxml.jackson.annotation.JsonValue; + /** * Class for an ASN.1 octet string. */ -public class Asn1OctetString extends Asn1CharacterString { +public class Asn1OctetString implements Asn1Type { + + protected final int minLength; + protected final int maxLength; + protected String value; + + @JsonValue + public String getValue() { + return value; + } public Asn1OctetString(int minLength, int maxLength) { - super(minLength, maxLength); + this.minLength = minLength; + this.maxLength = maxLength; + } + + public boolean validate(String aValue) { + if (aValue == null) return true; + // Size of hex format string can be 2 * byte size + // TODO validate valid hex string digit are + return aValue.length() >= 2 * minLength && aValue.length() <= 2 * maxLength; } } diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/XmlUtils.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/XmlUtils.java new file mode 100644 index 000000000..b668107d3 --- /dev/null +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/utils/XmlUtils.java @@ -0,0 +1,169 @@ +package us.dot.its.jpo.ode.plugin.utils; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Formatter; +import java.util.List; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.SneakyThrows; + +/** + * XMl Utilities + */ +public class XmlUtils { + + @SneakyThrows + public static List tokenize(String xml) { + var factory = XMLInputFactory.newInstance(); + XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(xml)); + return readTokens(reader); + } + + public static List readTokens(XMLStreamReader xmlReader) throws XMLStreamException { + var tokens = new ArrayList(); + var firstToken = addToken(xmlReader, tokens); + while (xmlReader.hasNext()) { + xmlReader.next(); + var thisToken = addToken(xmlReader, tokens); + if (firstToken == null) { + firstToken = thisToken; + } + if (thisToken != null && thisToken.isLast && thisToken.text.equals(firstToken.text)){ + break; + } + } + return mergeEmptyElements(tokens); + } + + @SneakyThrows + public static List readTokens(XMLStreamReader xmlReader, String endElement) { + var tokens = new ArrayList(); + addToken(xmlReader, tokens); + + while (xmlReader.hasNext()) { + xmlReader.next(); + XmlToken token = addToken(xmlReader, tokens); + if (token != null && token.isLast && token.text.equals(endElement)) { + tokens.removeLast(); + break; + } + } + return mergeEmptyElements(tokens); + } + + private static XmlToken addToken(XMLStreamReader xmlReader, List tokens) { + XmlToken token = null; + if (xmlReader.hasName()) { + QName name = xmlReader.getName(); + if (xmlReader.isStartElement()) { + token = new XmlToken(name.getLocalPart(), true, false); + tokens.add(token); + } else if (xmlReader.isEndElement()) { + token = new XmlToken(name.getLocalPart(), false, true); + tokens.add(token); + } + } else if (xmlReader.hasText() && !xmlReader.isWhiteSpace()) { + token = new XmlToken(xmlReader.getText(), false, false); + tokens.add(token); + } + return token; + } + + // Merge adjacent elements with no text between into empty elements to + // match the asn.1 style for enumerations and booleans. + private static List mergeEmptyElements(final List xmlTokens) { + final var mergedList = new ArrayList(); + int i = 0; + while (i < xmlTokens.size()) { + XmlToken token1 = xmlTokens.get(i); + if (i == xmlTokens.size() - 1) { + mergedList.add(token1); + break; + } + XmlToken token2 = xmlTokens.get(i + 1); + if (token1.isFirst && token2.isLast && token1.text.equals(token2.text)) { + // Combine into empty element and skip 2 + mergedList.add(new XmlToken(token1.text, true, true)); + i += 2; + } else { + // Don't change + mergedList.add(token1); + i++; + } + } + return mergedList; + } + + public static String stringifyTokens(List tokens) { + var f = new Formatter(); + for (XmlToken token : tokens) { + final String text = token.text; + if (token.isFirst && token.isLast) { + // Empty element + f.format("<%s/>", text); + } else if (token.isFirst) { + // Start element + f.format("<%s>", text); + } else if (token.isLast) { + // End element + f.format("", text); + } else { + // Text value + f.format(text); + } + } + return f.toString(); + } + + public static List> groupTopLevelTokens(final List tokens) { + XmlToken topLevel = null; + var tokenLists = new ArrayList>(); + List tokenList = null; + for (XmlToken token : tokens) { + if (topLevel == null && token.isFirst) { + // Start list + topLevel = token; + tokenList = new ArrayList(); + tokenList.add(token); + } else if (topLevel != null && token.isLast && token.text.equals(topLevel.text)) { + // complete list + tokenList.add(token); + topLevel = null; + tokenLists.add(tokenList); + } else if (tokenList != null) { + tokenList.add(token); + } + } + return tokenLists; + } + + public static List unwrap(final List tokens) { + // Remove first and last + if (tokens.size() > 2) { + return tokens.subList(1, tokens.size() - 1); + } else { + return tokens; + } + } + + public static List wrap(final List tokens, String wrapper) { + var wrapped = new ArrayList(); + wrapped.add(new XmlToken(wrapper, true, false)); + wrapped.addAll(tokens); + wrapped.add(new XmlToken(wrapper, false, true)); + return wrapped; + } + + @AllArgsConstructor + @Data + public static class XmlToken { + String text; + boolean isFirst; + boolean isLast; + } +} diff --git a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java index 56b627476..c3af40e40 100644 --- a/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java +++ b/jpo-ode-plugins/src/test/java/us/dot/its/jpo/ode/plugin/j2735/travelerinformation/NodeAttributeSetLLTest.java @@ -37,4 +37,5 @@ public void testSerializeJson_dWidth_dElevation() throws JsonProcessingException private static final String DWITDH_DELEVATION_ONLY_JSON = """ {"dWidth":162,"dElevation":424}"""; + } From a397df027559604ef7155eefbfbf8ecf2ec2e76c Mon Sep 17 00:00:00 2001 From: Ivan Yourshaw <39739503+iyourshaw@users.noreply.github.com> Date: Mon, 9 Dec 2024 00:41:26 -0700 Subject: [PATCH 146/264] itis, region, fix tests --- .../jpo/ode/plugin/j2735/itis/ITIScodes.java | 44 ++++++------ .../plugin/j2735/itis/ITIScodesAndText.java | 42 ++++++----- .../j2735/itis/ITIScodesAndTextSequence.java | 72 +++++++++---------- .../jpo/ode/plugin/j2735/itis/ITIStext.java | 40 +++++------ .../plugin/j2735/region/Reg_ComputedLane.java | 42 ++++++----- .../j2735/region/Reg_GeographicalPath.java | 42 ++++++----- .../j2735/region/Reg_GeometricProjection.java | 42 ++++++----- .../j2735/region/Reg_LaneDataAttribute.java | 52 +++++++------- .../j2735/region/Reg_NodeAttributeSetLL.java | 42 ++++++----- .../j2735/region/Reg_NodeAttributeSetXY.java | 42 ++++++----- .../j2735/region/Reg_NodeOffsetPointLL.java | 42 ++++++----- .../j2735/region/Reg_NodeOffsetPointXY.java | 52 +++++++------- .../plugin/j2735/region/Reg_Position3D.java | 52 +++++++------- .../j2735/region/Reg_TravelerInformation.java | 42 ++++++----- .../coder/OdeTimDataCreatorHelperTest.java | 1 + .../OdeTimDataCreatorHelper_TIM_JSON.json | 2 +- 16 files changed, 310 insertions(+), 341 deletions(-) diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java index a1533f7bf..0c2aee157 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodes.java @@ -1,33 +1,33 @@ -package us.dot.its.jpo.ode.plugin.j2735.itis; - -import us.dot.its.jpo.ode.plugin.types.Asn1Integer; -import com.fasterxml.jackson.annotation.JsonCreator; -import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.itis; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import us.dot.its.jpo.ode.plugin.serialization.IntegerDeserializer; +import us.dot.its.jpo.ode.plugin.types.Asn1Integer; + +@JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) public class ITIScodes extends Asn1Integer { public ITIScodes() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java index 10263c63a..49932c026 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndText.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.itis; - -import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.itis; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.types.Asn1SequenceOf; + @JsonInclude(Include.NON_NULL) public class ITIScodesAndText extends Asn1SequenceOf { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java index e7cbc6926..ff7f8459e 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIScodesAndTextSequence.java @@ -1,69 +1,61 @@ -package us.dot.its.jpo.ode.plugin.j2735.itis; - -import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import us.dot.its.jpo.ode.plugin.types.Asn1Choice; -import java.util.List; -import java.util.Optional; -import us.dot.its.jpo.ode.plugin.types.Asn1Type; -import lombok.Getter; -import lombok.Setter; -import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.itis; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import us.dot.its.jpo.ode.plugin.annotations.Asn1Property; +import us.dot.its.jpo.ode.plugin.types.Asn1Choice; +import us.dot.its.jpo.ode.plugin.types.Asn1Sequence; + @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @Getter @Setter public class ITIScodesAndTextSequence extends Asn1Sequence { - @Asn1Property(tag = 0) + @Asn1Property(tag = 0, name = "item") + @JsonProperty("item") private ItemChoice item; @Getter @Setter @JsonInclude(Include.NON_NULL) public static class ItemChoice extends Asn1Choice { - @Asn1Property(tag = 0) - @JsonDeserialize(using = ITIScodes.ITIScodesDeserializer.class) + @Asn1Property(tag = 0, name = "itis") + @JsonProperty("itis") private ITIScodes itis; - @Asn1Property(tag = 1) + @Asn1Property(tag = 1, name = "text") + @JsonProperty("text") private ITIStext text; ItemChoice() { super(false); } - - @Override - protected List> listTypes() { - return null; - } } ITIScodesAndTextSequence() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java index 6af08f7e5..c5fa99f4f 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/itis/ITIStext.java @@ -1,32 +1,30 @@ -package us.dot.its.jpo.ode.plugin.j2735.itis; - -import us.dot.its.jpo.ode.plugin.types.IA5String; -import com.fasterxml.jackson.annotation.JsonCreator; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.itis; + +import com.fasterxml.jackson.annotation.JsonCreator; +import us.dot.its.jpo.ode.plugin.types.IA5String; + public class ITIStext extends IA5String { public ITIStext() { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java index 3410edc35..8c3920fb7 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_ComputedLane.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_ComputedLane extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java index 9c629cc83..98d8ab03c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeographicalPath.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_GeographicalPath extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java index 711b68a85..b6697ef74 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_GeometricProjection.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_GeometricProjection extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java index 4c2319fcc..f40f2063c 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_LaneDataAttribute.java @@ -1,40 +1,38 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; -import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import us.dot.its.jpo.ode.plugin.j2735.addgrpb.LaneDataAttribute_addGrpBReg_LaneDataAttribute; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") @JsonSubTypes({ diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java index 609034278..c15b304da 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetLL.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_NodeAttributeSetLL extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java index e2c39d8f7..0b32ef5b8 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeAttributeSetXY.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_NodeAttributeSetXY extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java index 7ecbbd259..278223d23 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointLL.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_NodeOffsetPointLL extends RegionalExtension { diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java index 56bc82e1f..727bc3433 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_NodeOffsetPointXY.java @@ -1,40 +1,38 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; -import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import us.dot.its.jpo.ode.plugin.j2735.addgrpb.NodeOffsetPointXY_addGrpBReg_NodeOffsetPointXY; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") @JsonSubTypes({ diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java index 29ddd373b..b585b9da1 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_Position3D.java @@ -1,41 +1,39 @@ +/*============================================================================== + * + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT + * + *------------------------------------------------------------------------------ + * Copyright 2024 USDOT + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + *============================================================================*/ + package us.dot.its.jpo.ode.plugin.j2735.region; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; +import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; -import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import com.fasterxml.jackson.annotation.JsonTypeInfo.As; -import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo.Id; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes; import us.dot.its.jpo.ode.plugin.annotations.Asn1ParameterizedTypes.IdType; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; import us.dot.its.jpo.ode.plugin.j2735.addgrpb.Position3D_addGrpBReg_Position3D; import us.dot.its.jpo.ode.plugin.j2735.addgrpc.Position3D_addGrpCReg_Position3D; -/** - * - ******************************************************************************* - * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT - * - ******************************************************************************* - * Copyright 2024 USDOT - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ****************************************************************************** - * - */ @JsonInclude(Include.NON_NULL) @JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "regionId") @JsonSubTypes({@JsonSubTypes.Type(value = Position3D_addGrpBReg_Position3D.class, name = "2"), diff --git a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java index 6a817cb5b..6921451e9 100644 --- a/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java +++ b/jpo-ode-plugins/src/main/java/us/dot/its/jpo/ode/plugin/j2735/region/Reg_TravelerInformation.java @@ -1,33 +1,31 @@ -package us.dot.its.jpo.ode.plugin.j2735.region; - -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonInclude.Include; -import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; - -/** - * - ******************************************************************************* +/*============================================================================== * - * This source file was generated by a tool. Beware manual edits might be - * overwritten in future releases. asn1jvm v1.0-SNAPSHOT + * This source file was generated by a tool. + * Beware manual edits might be overwritten in future releases. + * asn1jvm v1.0-SNAPSHOT * - ******************************************************************************* + *------------------------------------------------------------------------------ * Copyright 2024 USDOT - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. - ****************************************************************************** - * - */ + *============================================================================*/ + +package us.dot.its.jpo.ode.plugin.j2735.region; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import us.dot.its.jpo.ode.plugin.j2735.common.RegionalExtension; + @JsonInclude(Include.NON_NULL) abstract public class Reg_TravelerInformation extends RegionalExtension { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java index 37a491a76..b18e1f70d 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java @@ -36,6 +36,7 @@ public void testCreateOdeTimDataFromDecoded() throws IOException { OdeTimData timData; try { timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); + System.out.println(timData.toString()); assertEquals(expectedJsonString, timData.toString()); } catch (XmlUtilsException e) { e.printStackTrace(); diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json index 3e096b913..32ee1d052 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"long":-1717691068,"elevation":53848},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"long":1616508908,"elevation":38736},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"long":-1285139143,"elevation":48475},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"laneAngle":101},{"laneAngle":62},{"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]},{"pathEndPointAngle":-8},{"laneCrownPointLeft":35}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"speedLimits":[{"type":"maxSpeedInSchoolZoneWhenChildrenArePresent","speed":3453},{"type":"truckMinSpeed","speed":7876}]},{"speedLimits":[{"type":"truckMinSpeed","speed":2097}]},{"laneAngle":-82}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":58},{"pathEndPointAngle":1},{"pathEndPointAngle":25},{"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"long":270580409,"elevation":16367},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"long":664850545,"elevation":32186},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"long":-685153664,"elevation":57976},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"long":1108489970,"elevation":9059},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":-87},{"laneCrownPointRight":4},{"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"laneAngle":60},{"pathEndPointAngle":-95}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"long":1670812734,"elevation":46812},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"long":772185922,"elevation":9413},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"long":313588249,"elevation":50308},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"long":-533287210,"elevation":51107},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":18},{"pathEndPointAngle":24},{"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109},{"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"long":353479827,"elevation":59458},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"long":-814772254,"elevation":45059},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"long":759386724,"elevation":4505},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"long":-508985739,"elevation":9512},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"long":-1208779998,"elevation":35858},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"long":-804103995,"elevation":43319},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"long":1697199162,"elevation":46636},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"long":-77527193,"elevation":35728},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"long":88284632,"elevation":45419},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"long":1462406911,"elevation":57912},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file From 92c4504efe60d4d7cbf6d7aea2a4775e1b095f30 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 9 Dec 2024 09:48:47 -0700 Subject: [PATCH 147/264] Update attribution documentation to note where the TIM POJOs came from --- ATTRIBUTION.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 4a6dc79da..8a3c971bb 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -12,3 +12,17 @@ The developers also wish to acknowledge the following leaders and contributors: * Oakridge National Laboratories: Jason Carter and Aaron Ferber Thanks to the ITS Joint Program Office for their support of the effort. + +The J2735 Traveler Information classes were generated using asn1jvm, which is a new ASN.1 compiler targeting Java. The asn1jvm tool is currently capable of compiling the 2016 version of the J2735 ASN.1 specification to Java classes which are capable of serializing and deserializing XER and JER. The output of the tool includes classes with Jackson annotations for each type in the specification, and a runtime library containing base classes for ASN.1 types and custom Jackson serializers and deserialers. The raw output of the tool and associated runtime library are here: https://github.com/iyourshaw/j2735-2016-java + +The generated classes were edited for compatibility with the 2020 version of the specification as follows: + +* TimDatFrame.java, fields renamed: + * sspTimRights -> notUsed + * sspLocationRights -> notUsed1 + * sspMsgRights1 -> notUsed2 + * sspMsgRights2 -> notUsed3 + * duratonTime -> durationTime +* Classes were moved to Java packages to be consistent with the module organization scheme in the 2020+ versions of J2735, and with Java package naming conventions (lowercase), and existing ODE package naming. Specifically, instead being in a `DSRC` package, the TIM-related classes were moved to `us.dot.its.jpo.ode.plugin.j2735.travelerinformation`, and `us.dot.its.jpo.ode.plugin.j2735.common` packages. + +The top level TravelerInformation class was also edited, by changing its base class to `us.dot.its.jpo.ode.plugin.asn1.Asn1Object` to enable it to plug directily into the existing `OdeData`/`OdeMsgPayload` data structure. \ No newline at end of file From 8c35ad2d8af597861e4cf5746990465146e15f1e Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:07:20 -0700 Subject: [PATCH 148/264] Address pull request comments --- .../ode/coder/OdeTimDataCreatorHelper.java | 14 +++++----- .../coder/OdeTimDataCreatorHelperTest.java | 28 ++++++------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java index 08cc320a5..0eddd3a73 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelper.java @@ -1,10 +1,11 @@ package us.dot.its.jpo.ode.coder; -import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -import java.io.IOException; + +import lombok.extern.slf4j.Slf4j; + import us.dot.its.jpo.ode.context.AppContext; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimData; @@ -20,6 +21,7 @@ /** * Helper class for deserializing TIM messages in XML/XER format into POJOs. */ +@Slf4j public class OdeTimDataCreatorHelper { /** @@ -45,17 +47,15 @@ public static OdeTimData createOdeTimDataFromDecoded(String consumedData) try { jsonNode = objectMapper.readTree(receivedMessageDetails.toJson()); object.set(AppContext.RECEIVEDMSGDETAILS_STRING, jsonNode); - } catch (JsonProcessingException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + } catch (Exception e) { + log.error("Failed to read JSON node: {}", e.getMessage()); } } OdeTimMetadata metadata = (OdeTimMetadata) JsonUtils.fromJson(metadataNode.toString(), OdeTimMetadata.class); - if (metadata.getSchemaVersion() <= 4) { + if (metadata != null && metadata.getSchemaVersion() <= 4) { metadata.setReceivedMessageDetails(null); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java index b18e1f70d..b8c1efd68 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java @@ -1,32 +1,23 @@ package us.dot.its.jpo.ode.coder; import static org.junit.Assert.assertEquals; -import static org.junit.jupiter.api.Assertions.fail; import java.io.File; -import java.io.IOException; import java.nio.file.Files; import org.junit.jupiter.api.Test; import us.dot.its.jpo.ode.model.OdeTimData; import us.dot.its.jpo.ode.util.XmlUtils; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -/** - * Tests for the OdeTimDataCreatorHelper class. - */ -public class OdeTimDataCreatorHelperTest { +class OdeTimDataCreatorHelperTest { @Test - public void testCreateOdeTimDataFromDecoded() throws IOException { + public void testCreateOdeTimDataFromDecoded() throws Exception { String xmlFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_XER.xml"; File xmlFile = new File(xmlFilePath); byte[] xmlData = Files.readAllBytes(xmlFile.toPath()); String xmlString = new String(xmlData); - try { - XmlUtils.toObjectNode(xmlString); - } catch (XmlUtilsException e) { - fail("XML parsing error:" + e); - } + + XmlUtils.toObjectNode(xmlString); String jsonFilePath = "src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json"; @@ -34,13 +25,10 @@ public void testCreateOdeTimDataFromDecoded() throws IOException { byte[] jsonData = Files.readAllBytes(jsonFile.toPath()); String expectedJsonString = new String(jsonData); OdeTimData timData; - try { - timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); - System.out.println(timData.toString()); - assertEquals(expectedJsonString, timData.toString()); - } catch (XmlUtilsException e) { - e.printStackTrace(); - } + + timData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(xmlString); + + assertEquals(expectedJsonString, timData.toString()); } } From 7dccf75924d84d38273286bad6a3b731344cc769 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:10:05 -0700 Subject: [PATCH 149/264] Update the imported assertEquals --- .../us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java index b8c1efd68..0abc02d69 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/coder/OdeTimDataCreatorHelperTest.java @@ -1,6 +1,6 @@ package us.dot.its.jpo.ode.coder; -import static org.junit.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.File; import java.nio.file.Files; From 9e48c45927694dd91f0c93fe127f31b6ae896890 Mon Sep 17 00:00:00 2001 From: Michael7371 <40476797+Michael7371@users.noreply.github.com> Date: Tue, 10 Dec 2024 11:35:17 -0700 Subject: [PATCH 150/264] update to TimData class to allow for Tim payload serialization to work properly. Updates to affected unit tests --- .../java/us/dot/its/jpo/ode/model/OdeTimData.java | 15 +++++++++++++++ .../us/dot/its/jpo/ode/model/OdeTimPayload.java | 6 +++++- .../jpo/ode/traveler/TimTransmogrifierTest.java | 2 +- .../OdeTimDataCreatorHelper_TIM_JSON.json | 2 +- .../traveler/aemInputContainingCircleGeometry.xml | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimData.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimData.java index 1f1fac5f4..22d99af05 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimData.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimData.java @@ -15,6 +15,9 @@ ******************************************************************************/ package us.dot.its.jpo.ode.model; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.*; + public class OdeTimData extends OdeData { private static final long serialVersionUID = 2057040404896561615L; @@ -29,4 +32,16 @@ public OdeTimData(OdeMsgMetadata metadata, OdeMsgPayload payload) { super(metadata, payload); } + @Override + @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeTimMetadata.class) + public void setMetadata(OdeMsgMetadata metadata) { + super.setMetadata(metadata); + } + + @Override + @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeTimPayload.class) + public void setPayload(OdeMsgPayload payload) { + super.setPayload(payload); + } + } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java index 1a642b0ca..b6d34dfe7 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeTimPayload.java @@ -16,6 +16,9 @@ package us.dot.its.jpo.ode.model; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + import us.dot.its.jpo.ode.plugin.j2735.OdeTravelerInformationMessage; import us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation; @@ -36,7 +39,8 @@ public OdeTimPayload(OdeTravelerInformationMessage tim) { this.setData(tim); } - public OdeTimPayload(TravelerInformation tim) { + @JsonCreator + public OdeTimPayload(@JsonProperty("data") TravelerInformation tim) { super(tim); this.setData(tim); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 221d72868..efa926b66 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -249,7 +249,7 @@ void testConvertToXMLMessageFrame() staticOdeMsgMetadata.setSchemaVersion(Integer.parseInt(schemaVersion)); String actualXML = TimTransmogrifier.convertToXml(null, encodableTID, staticOdeMsgMetadata, staticSerialId); - var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPERMessageFrame31", DateTimeUtils.now(), schemaVersion); + var expected = String.format("us.dot.its.jpo.ode.model.OdeTimPayload6c33f802-418d-4b67-89d1-326b4fc8b1e31000%s%s0false42.537903-83.47790342.305753-82.842753thirtyminutes2017-06-01T17:47:11-05:002018-03-01T17:47:11-05:15MessageFrameMessageFrameUPER31MessageFrame", DateTimeUtils.now(), schemaVersion); assertEquals(expected, actualXML); } diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json index 32ee1d052..ed0fa1a8a 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.coder/OdeTimDataCreatorHelper_TIM_JSON.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"long":-1717691068,"elevation":53848},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"long":1616508908,"elevation":38736},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"long":-1285139143,"elevation":48475},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"laneAngle":101},{"laneAngle":62},{"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]},{"pathEndPointAngle":-8},{"laneCrownPointLeft":35}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"speedLimits":[{"type":"maxSpeedInSchoolZoneWhenChildrenArePresent","speed":3453},{"type":"truckMinSpeed","speed":7876}]},{"speedLimits":[{"type":"truckMinSpeed","speed":2097}]},{"laneAngle":-82}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":58},{"pathEndPointAngle":1},{"pathEndPointAngle":25},{"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"long":270580409,"elevation":16367},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"long":664850545,"elevation":32186},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"long":-685153664,"elevation":57976},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"long":1108489970,"elevation":9059},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":-87},{"laneCrownPointRight":4},{"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"laneAngle":60},{"pathEndPointAngle":-95}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"long":1670812734,"elevation":46812},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"long":772185922,"elevation":9413},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"long":313588249,"elevation":50308},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"long":-533287210,"elevation":51107},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":18},{"pathEndPointAngle":24},{"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109},{"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"long":353479827,"elevation":59458},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"long":-814772254,"elevation":45059},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"long":759386724,"elevation":4505},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"long":-508985739,"elevation":9512},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"long":-1208779998,"elevation":35858},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"long":-804103995,"elevation":43319},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"long":1697199162,"elevation":46636},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"long":-77527193,"elevation":35728},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"long":88284632,"elevation":45419},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"long":1462406911,"elevation":57912},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"long":-1717691068,"elevation":53848},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"long":1616508908,"elevation":38736},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"long":-1285139143,"elevation":48475},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"laneAngle":101},{"laneAngle":62},{"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]},{"pathEndPointAngle":-8},{"laneCrownPointLeft":35}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"speedLimits":[{"type":"maxSpeedInSchoolZoneWhenChildrenArePresent","speed":3453},{"type":"truckMinSpeed","speed":7876}]},{"speedLimits":[{"type":"truckMinSpeed","speed":2097}]},{"laneAngle":-82}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":58},{"pathEndPointAngle":1},{"pathEndPointAngle":25},{"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"long":270580409,"elevation":16367},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"long":664850545,"elevation":32186},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"long":-685153664,"elevation":57976},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"long":1108489970,"elevation":9059},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":-87},{"laneCrownPointRight":4},{"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"laneAngle":60},{"pathEndPointAngle":-95}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"long":1670812734,"elevation":46812},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"long":772185922,"elevation":9413},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"long":313588249,"elevation":50308},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"long":-533287210,"elevation":51107},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":18},{"pathEndPointAngle":24},{"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109},{"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"long":353479827,"elevation":59458},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"long":-814772254,"elevation":45059},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"long":759386724,"elevation":4505},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"long":-508985739,"elevation":9512},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"long":-1208779998,"elevation":35858},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"long":-804103995,"elevation":43319},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"long":1697199162,"elevation":46636},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"long":-77527193,"elevation":35728},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"long":88284632,"elevation":45419},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"long":1462406911,"elevation":57912},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]},"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml index d9de3debd..ad8e2f4e6 100644 --- a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/traveler/aemInputContainingCircleGeometry.xml @@ -1 +1 @@ -us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPERMessageFrame3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000
411535930-104655785018240
50
004868null
\ No newline at end of file +us.dot.its.jpo.ode.model.OdeTimPayloadtestStreamId10002024-11-05T16:51:14.473Z786402024-09-25T10:00:00.000ZTMCfalse8D442FF4020C6B1A012024-09-25T10:00:00.000Z3PUT172.0.0.1usernamepassword3500021NTCIP12188331118310002024-09-25T10:00:00.0Z2024-09-30T10:00:00.0Z14MessageFrameMessageFrameUPER3113865208D442FF4020C6B1A01null0411535930-104655785011111111111111112024386520864050myregionname00411535930-1046557850111100001111000011110000111100000
411535930-104655785018240
50
004868null
MessageFrame
\ No newline at end of file From d7fc79afec11001cfb8d19be06089c2f3fafd58a Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Wed, 11 Dec 2024 13:19:07 -0700 Subject: [PATCH 151/264] Migrate UDPRecievers to use Spring Kafka (#129) *refactor: extract method for generating kafka consumer properties in KafkaConsumerConfig *refactor: extract method for generating kafka producer properties in KafkaProducerConfig.java *test: complete test for BsmReceiverTest by testing serial-id is not equal, removing from both, and comparing the expected and actual JSON *refactor: swap Spring Kafka in for BsmReceiver and BsmReceiverTest *refactor: remove unused OdeKafkaProperties bean from BsmReceiverTest *style: reformat UperUtil with checkstyle.xml *test: use SpringBootTest slices in MapReceiverTest to reduce setup/teardown cost of integration test *style: reformat UdpHexDecoder.java *test: use SpringBootTest slices for smaller footprint with Asn1DecodeMAPJSONTest *test: use SpringBootTest slices for smaller footprint with Asn1DecodedDataRouterApprovalTest *chore: update BsmReceiverTest_ValidBSM.txt and BsmReceiverTest_ValidBSM_expected.json to use expected encoded value *test: add TimReceiverTest with inputs and expected value files *refactor: swap KafkaTemplate in for TimReceiver *style: reformat TimReceiver *style: reformat UdpHexDecoder.java *test: use value from scripts/tests/udpsender_ssm.py to populate SsmReceiverTest_ValidSSM.txt and the resulting SsmReceiverTest_ValidSSM_expected.json *refactor: swap KafkaTemplate in for SsmReceiver *test: use value from scripts/tests/udpsender_spat.py to populate SpatReceiverTest_ValidSPAT.txt and the resulting SpatReceiverTest_ValidSPAT_expected.json *refactor: swap KafkaTemplate in for SpatReceiver *test: use value from scripts/tests/udpsender_psm.py to populate PsmReceiverTest_ValidPSM.txt and the resulting PsmReceiverTest_ValidPSM_expected.json *refactor: swap KafkaTemplate in for PsmReceiver *test: use value from scripts/tests/udpsender_srm.py to populate SrmReceiverTest_ValidSRM.txt and the resulting SrmReceiverTest_ValidSRM_expected.json *refactor: swap KafkaTemplate in for SrmReceiver *refactor: encapsulate Confluent properties map creation in buildConfluentProperties and use where needed *test: use value from scripts/tests/udpsender_map.py to populate MapReceiverTest_ValidMAP.txt and the resulting MapReceiverTest_ValidMAP_expected.json *chore: added failureMsg to GenericReceiverTest for ease of test failure diagnoses *refactor: swap KafkaTemplate in for GenericReceiver *refactor: extract routeMessageByMessageType to remove NPE chance and reduce cognitive complexity *style: reformatted GenericReceiver *refactor: remove unused OdeKafkaProperties from UdpServicesController constructor *style: increase LineLength from 100 to 150 in checkstyle.xml to account for verbosity of Java and file names *style: corrected various checkstyle issues *feat: Add Kafka producer interceptor to block disabled topics Introduced a new `DisabledTopicsStringProducerInterceptor` to prevent messages from being sent to disabled Kafka topics as specified in `OdeKafkaProperties`. Updated `KafkaTemplate` instantiation to include this interceptor, ensuring messages to these topics are intercepted and logged. Additionally, added failing unit tests in `KafkaProducerConfigTest` to verify the interceptor's functionality. Signed-off-by: Matt Cook *refactor: Add exception for disabled Kafka topics Modified the Kafka interceptor to throw a DisabledTopicException when messages are sent to disabled topics. Updated tests to assert this exception and ensure that messages are not sent to disabled topics, while allowing messages to pass to enabled topics. Signed-off-by: Matt Cook *refactor: moved producer related kafka code under the `producer` subpackage Signed-off-by: Matt Cook *test: turn off auto-create topics in test kafka admin to prevent need for redundant try-catch blocks in test setups Signed-off-by: Matt Cook *refactor: Remove unused code handling disabled Kafka topics The `disabledTopics` feature and related logic have been removed to simplify the codebase. This change eliminates unnecessary complexity by discarding unutilized imports, fields, and methods tied to managing disabled topics. The `send` method has been integrated directly into the `handle` method for immediate message publishing to the specified Kafka topic. Signed-off-by: Matt Cook *refactor: reorganized methods in KafkaProducerConfig to colocated related methods for improved readability Signed-off-by: Matt Cook *test: Update KafkaProducerConfigTest to confirm the odeKafkaTemplate does not send to disabled topics Signed-off-by: Matt Cook * Add missing Javadocs to files in the changeset *feat: Introduced LoggingProducerListeners to provide debug logging for kafka producers Signed-off-by: Matt Cook *docs: Update documentation and restructure code for increased clarity Signed-off-by: Matt Cook *chore: Handle DisabledTopicException in UDP Receivers Added handling for DisabledTopicException across all UDP receivers. Now, when attempting to send data to a disabled Kafka topic, a warning is logged instead of an error. This change improves error handling and logging clarity for disabled topic scenarios. Signed-off-by: Matt Cook * test: add missing SRM test case to GenericReceiverTest Signed-off-by: Matt Cook * style: rename rm to serviceManager in UdpServicesController to improve readability Signed-off-by: Matt Cook --------- Signed-off-by: Matt Cook --- .github/workflows/checkstyle.yml | 2 +- checkstyle.xml | 2 +- .../dot/its/jpo/ode/OdeTimJsonTopology.java | 34 +- .../jpo/ode/kafka/ConfluentProperties.java | 38 +- .../jpo/ode/kafka/KafkaConsumerConfig.java | 217 +++++---- .../jpo/ode/kafka/KafkaProducerConfig.java | 59 --- .../listeners/Asn1DecodeMAPJSONListener.java | 90 ++-- .../listeners/Asn1DecodedDataListener.java | 124 ++--- .../producer/DisabledTopicException.java | 19 + .../DisabledTopicsProducerInterceptor.java | 66 +++ .../kafka/producer/KafkaProducerConfig.java | 132 ++++++ .../producer/LoggingProducerListener.java | 43 ++ .../us/dot/its/jpo/ode/udp/UdpHexDecoder.java | 438 +++++++++++------- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 100 ++-- .../udp/controller/UdpServicesController.java | 50 +- .../jpo/ode/udp/generic/GenericReceiver.java | 203 ++++---- .../dot/its/jpo/ode/udp/map/MapReceiver.java | 91 ++-- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 90 ++-- .../its/jpo/ode/udp/spat/SpatReceiver.java | 89 ++-- .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 91 ++-- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 83 ++-- .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 90 ++-- .../us/dot/its/jpo/ode/uper/UperUtil.java | 347 ++++++++------ .../jpo/ode/kafka/Asn1DecodeMAPJSONTest.java | 115 +++-- .../ode/kafka/ConfluentPropertiesTest.java | 27 ++ .../ode/kafka/KafkaProducerConfigTest.java | 123 +++++ .../Asn1DecodedDataRouterApprovalTest.java | 170 ++++--- .../asn1/message/Asn1DecodeBSMJSONTest.java | 78 ++-- .../asn1/message/Asn1DecodePSMJSONTest.java | 78 ++-- .../asn1/message/Asn1DecodeSPATJSONTest.java | 78 ++-- .../asn1/message/Asn1DecodeSRMJSONTest.java | 80 ++-- .../asn1/message/Asn1DecodeSSMJSONTest.java | 79 ++-- .../asn1/message/Asn1DecodeTIMJSONTest.java | 80 ++-- .../ode/test/utilities/ApprovalTestCase.java | 58 +++ .../test/utilities/EmbeddedKafkaHolder.java | 54 +++ .../jpo/ode/test/utilities/TestUDPClient.java | 51 ++ .../ode/testUtilities/ApprovalTestCase.java | 49 -- .../testUtilities/EmbeddedKafkaHolder.java | 30 -- .../jpo/ode/testUtilities/TestUDPClient.java | 36 -- .../its/jpo/ode/udp/bsm/BsmReceiverTest.java | 112 +++++ .../ode/udp/generic/GenericReceiverTest.java | 194 ++++++++ .../its/jpo/ode/udp/map/MapReceiverTest.java | 172 ++++--- .../its/jpo/ode/udp/psm/PsmReceiverTest.java | 105 +++++ .../jpo/ode/udp/spat/SpatReceiverTest.java | 110 +++++ .../its/jpo/ode/udp/srm/SrmReceiverTest.java | 108 +++++ .../its/jpo/ode/udp/ssm/SsmReceiverTest.java | 108 +++++ .../its/jpo/ode/udp/tim/TimReceiverTest.java | 111 +++++ .../src/test/resources/application.yaml | 2 + .../UDPMAP_To_EncodedJSON_Validation.json | 8 +- .../ode/udp/bsm/BsmReceiverTest_ValidBSM.txt | 1 + .../BsmReceiverTest_ValidBSM_expected.json | 38 ++ .../ode/udp/map/MapReceiverTest_ValidMAP.txt | 1 + .../MapReceiverTest_ValidMAP_expected.json | 28 ++ .../ode/udp/psm/PsmReceiverTest_ValidPSM.txt | 1 + .../PsmReceiverTest_ValidPSM_expected.json | 28 ++ .../udp/spat/SpatReceiverTest_ValidSPAT.txt | 1 + .../SpatReceiverTest_ValidSPAT_expected.json | 29 ++ .../srm/SrmReceiverTest_ExpectedOutput.json | 28 ++ .../ode/udp/srm/SrmReceiverTest_ValidData.txt | 1 + .../ode/udp/ssm/SsmReceiverTest_ValidSSM.txt | 1 + .../SsmReceiverTest_ValidSSM_expected.json | 28 ++ .../ode/udp/tim/TimReceiverTest_ValidTIM.txt | 1 + .../TimReceiverTest_ValidTIM_expected.json | 27 ++ 63 files changed, 3455 insertions(+), 1472 deletions(-) delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/ConfluentPropertiesTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/ApprovalTestCase.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/TestUDPClient.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP_expected.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json diff --git a/.github/workflows/checkstyle.yml b/.github/workflows/checkstyle.yml index ad337bc7e..768e663ac 100644 --- a/.github/workflows/checkstyle.yml +++ b/.github/workflows/checkstyle.yml @@ -13,4 +13,4 @@ jobs: github_token: ${{ secrets.github_token }} reporter: github-pr-review level: warning - checkstyle_config: 'checkstyle.xml' \ No newline at end of file + checkstyle_config: './checkstyle.xml' \ No newline at end of file diff --git a/checkstyle.xml b/checkstyle.xml index fc79dfe84..f17b829fb 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -51,7 +51,7 @@ - + diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java index 448d56036..6c6e2b1c0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/OdeTimJsonTopology.java @@ -13,6 +13,7 @@ import org.apache.kafka.streams.state.Stores; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; + /** * The OdeTimJsonTopology class sets up and manages a Kafka Streams topology * for processing TIM (Traveler Information Message) JSON data from the @@ -26,11 +27,13 @@ public class OdeTimJsonTopology { private final KafkaStreams streams; /** - * Constructs a new OdeTimJsonTopology. + * Constructs an instance of OdeTimJsonTopology to set up and manage a Kafka Streams + * topology for processing TIM JSON data. * - * @param odeKafkaProps The Apache Kafka properties that will be used by the topology with Kafka. - * @param topic The Apache Kafka topic name. - **/ + * @param odeKafkaProps the properties containing Kafka configuration, including brokers + * and optional Confluent-specific configuration for authentication. + * @param topic the Kafka topic from which TIM JSON data is consumed to build the topology. + */ public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps, String topic) { Properties streamsProperties = new Properties(); @@ -40,11 +43,12 @@ public OdeTimJsonTopology(OdeKafkaProperties odeKafkaProps, String topic) { streamsProperties.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.StringSerde.class); if ("CONFLUENT".equals(odeKafkaProps.getKafkaType())) { - streamsProperties.put("sasl.jaas.config", odeKafkaProps.getConfluent().getSaslJaasConfig()); + streamsProperties.putAll(odeKafkaProps.getConfluent().buildConfluentProperties()); } streams = new KafkaStreams(buildTopology(topic), streamsProperties); - streams.setStateListener((newState, oldState) -> - log.info("Transitioning from {} to {}", oldState, newState)); + streams.setStateListener((newState, oldState) -> + log.info("Transitioning from {} to {}", oldState, newState) + ); streams.start(); } @@ -58,14 +62,16 @@ public boolean isRunning() { } /** - * Build the topology with a provided topic name. + * Builds a Kafka Streams topology for processing TIM JSON data. * - * @param topic The topic name. - **/ + * @param topic the Kafka topic from which TIM JSON data is consumed and used + * to build the topology. + * @return the constructed Kafka Streams topology. + */ public Topology buildTopology(String topic) { StreamsBuilder builder = new StreamsBuilder(); - builder.table(topic, Materialized.as( - Stores.inMemoryKeyValueStore("timjson-store"))); + builder.table(topic, + Materialized.as(Stores.inMemoryKeyValueStore("timjson-store"))); return builder.build(); } @@ -76,9 +82,7 @@ public Topology buildTopology(String topic) { **/ public String query(String uuid) { return (String) streams.store( - StoreQueryParameters.fromNameAndType( - "timjson-store", - QueryableStoreTypes.keyValueStore())) + StoreQueryParameters.fromNameAndType("timjson-store", QueryableStoreTypes.keyValueStore())) .get(uuid); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java index 25d082cff..2ab451934 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/ConfluentProperties.java @@ -1,19 +1,43 @@ package us.dot.its.jpo.ode.kafka; +import java.util.HashMap; +import java.util.Map; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Configuration; +/** + * A configuration properties class that holds configuration settings for Confluent Kafka + * integration. This class is designed to be used with Spring Boot's configuration properties + * mechanism, allowing for easy externalization and injection of property values. + * + *

This class provides a method to build a map of Confluent-specific Kafka properties, which + * includes authentication settings necessary for connecting to a Confluent-managed Kafka cluster. + */ @Configuration @ConfigurationProperties(prefix = "ode.kafka.confluent") @Data public class ConfluentProperties { - private String username; - private String password; - public String getSaslJaasConfig() { - return "org.apache.kafka.common.security.plain.PlainLoginModule required " + - "username=\"" + username + "\" " + - "password=\"" + password + "\";"; - } + private String username; + private String password; + + /** + * Builds and returns a map of configuration properties specific to Confluent Kafka integration. + * These properties include security configurations necessary for authentication with a + * Confluent-managed Kafka cluster using SASL_SSL and PLAIN mechanisms. + * + * @return a map containing Confluent Kafka properties with security protocol and SASL + * configurations including username and password. + */ + public Map buildConfluentProperties() { + Map props = new HashMap<>(); + props.put("ssl.endpoint.identification.algorithm", "https"); + props.put("security.protocol", "SASL_SSL"); + props.put("sasl.mechanism", "PLAIN"); + props.put("sasl.jaas.config", + "org.apache.kafka.common.security.plain.PlainLoginModule required " + "username=\"" + + username + "\" " + "password=\"" + password + "\";"); + return props; + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java index e5926f8f3..2b17bfb64 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.kafka; +import java.util.HashMap; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.common.serialization.StringDeserializer; import org.json.JSONObject; @@ -18,103 +20,152 @@ import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; import us.dot.its.jpo.ode.util.XmlUtils; -import java.util.HashMap; -import java.util.Map; - +/** + * Configures Kafka consumer settings and provides various consumer factories and listener container + * factories for handling different types of data in a Kafka messaging system. This class sets up + * the consumer properties, including any security configurations for Confluent deployments, and + * provides mechanisms to filter messages based on specific criteria. + */ @EnableKafka @Configuration @Slf4j public class KafkaConsumerConfig { - private final KafkaProperties kafkaProperties; - private final OdeKafkaProperties odeKafkaProperties; + private final KafkaProperties kafkaProperties; + private final OdeKafkaProperties odeKafkaProperties; - public KafkaConsumerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties odeKafkaProperties) { - this.kafkaProperties = kafkaProperties; - this.odeKafkaProperties = odeKafkaProperties; - } + /** + * Constructs a new instance of KafkaConsumerConfig with the specified Kafka properties. + * + * @param kafkaProperties The general Kafka properties used for configuring consumer settings. + * @param odeKafkaProperties The specific Ode Kafka properties which may include custom + * configurations relevant to the Ode system, possibly including + * brokers and other kafka-specific settings. + */ + public KafkaConsumerConfig(KafkaProperties kafkaProperties, + OdeKafkaProperties odeKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.odeKafkaProperties = odeKafkaProperties; + } - @Bean - public ConsumerFactory consumerFactory() { - var consumerProps = kafkaProperties.buildConsumerProperties(); - if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { - consumerProps.put("ssl.endpoint.identification.algorithm", "https"); - consumerProps.put("security.protocol", "SASL_SSL"); - consumerProps.put("sasl.mechanism", "PLAIN"); - consumerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); - } - return new DefaultKafkaConsumerFactory<>(consumerProps); - } + /** + * Creates and configures a {@link ConsumerFactory} for Kafka consumers with String key and + * value deserialization. The factory is configured using Kafka consumer properties defined + * in the application configuration. + * + * @return a {@link ConsumerFactory} instance configured to produce Kafka consumers with + * String key and value serialization. + */ + @Bean + public ConsumerFactory consumerFactory() { + return new DefaultKafkaConsumerFactory<>(getKafkaConsumerProperties()); + } - @Bean - public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { - ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); - factory.setConsumerFactory(consumerFactory()); - return factory; - } + /** + * Creates and configures a ConcurrentKafkaListenerContainerFactory for Kafka listeners. This + * factory is responsible for creating listener containers, which are used to receive messages + * from Kafka topics. + * + * @return a ConcurrentKafkaListenerContainerFactory setup with a defined consumer factory that + * determines how Kafka consumers are created and configured. + */ + @Bean + public ConcurrentKafkaListenerContainerFactory kafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = + new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + return factory; + } - @Bean - public ConsumerFactory odeMapDataConsumerFactory() { - Map props = new HashMap<>(kafkaProperties.buildConsumerProperties()); - if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { - props.put("ssl.endpoint.identification.algorithm", "https"); - props.put("security.protocol", "SASL_SSL"); - props.put("sasl.mechanism", "PLAIN"); - props.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); - } - return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(OdeMapData.class)); - } + /** + * Creates a Kafka {@link ConsumerFactory} for consuming messages with keys of type {@link String} + * and values of type {@link OdeMapData}. This method utilizes a {@link StringDeserializer} for + * deserializing the key and a {@link JsonDeserializer} for deserializing values of type + * {@link OdeMapData}. + * + *

The consumer factory is configured using Kafka properties, which are retrieved from the + * application's configuration settings. + * + * @return a configured {@link ConsumerFactory} for {@link String} keys and {@link OdeMapData} + * values. + */ + @Bean + public ConsumerFactory odeMapDataConsumerFactory() { + return new DefaultKafkaConsumerFactory<>(getKafkaConsumerProperties(), new StringDeserializer(), + new JsonDeserializer<>(OdeMapData.class)); + } - @Bean - public ConcurrentKafkaListenerContainerFactory odeMapDataConsumerListenerContainerFactory() { - ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); - factory.setConsumerFactory(odeMapDataConsumerFactory()); - return factory; - } + /** + * Creates and configures a ConcurrentKafkaListenerContainerFactory for consuming Kafka messages + * with keys of type String and values of type OdeMapData. The factory is configured with a + * consumer factory provided by the odeMapDataConsumerFactory method. + * + * @return a configured ConcurrentKafkaListenerContainerFactory instance for processing Kafka + * messages with keys of type String and values of type OdeMapData. + */ + @Bean + public ConcurrentKafkaListenerContainerFactory odeMapDataConsumerListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = + new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(odeMapDataConsumerFactory()); + return factory; + } - /** - * @return factory A listener factory that supports filtering out messages that don't match a specific pattern - *

- * @deprecated This method is intended to be short-lived. It exists to allow consumption via the Asn1DecodedDataRouter & - * the Asn1DecodedDataListener while we are migrating from hand-rolled Kafka implementation to Spring's Kafka implementation - */ - @Bean - @Deprecated(forRemoval = true) - public ConcurrentKafkaListenerContainerFactory tempFilteringKafkaListenerContainerFactory() { - ConcurrentKafkaListenerContainerFactory factory = new ConcurrentKafkaListenerContainerFactory<>(); - factory.setConsumerFactory(consumerFactory()); - factory.setRecordFilterStrategy(getFilterStrategySpringKafkaSupportedMessageTypesOnly()); + /** + * Creates a {@link ConcurrentKafkaListenerContainerFactory} for processing Kafka messages. This + * factory is configured to filter out certain messages based on a defined strategy. + * + * @return factory A listener factory that supports filtering out messages that don't match a + * specific pattern + * @deprecated This method is intended to be short-lived. It exists to allow consumption via the + * Asn1DecodedDataRouter & the Asn1DecodedDataListener while we are migrating from hand-rolled + * Kafka implementation to Spring's Kafka implementation + */ + @Bean + @Deprecated(forRemoval = true) + public ConcurrentKafkaListenerContainerFactory tempFilteringKafkaListenerContainerFactory() { + ConcurrentKafkaListenerContainerFactory factory = + new ConcurrentKafkaListenerContainerFactory<>(); + factory.setConsumerFactory(consumerFactory()); + factory.setRecordFilterStrategy(getFilterStrategySpringKafkaSupportedMessageTypesOnly()); - return factory; - } + return factory; + } + + /** + * While migrating to Spring Kafka the consumers provided from this factory will only consume (and + * ack) messages we support via the Spring Kafka implementation. All other messages will be + * handled by the Asn1DecodedDataRouter + * + * @return filter + */ + private static RecordFilterStrategy getFilterStrategySpringKafkaSupportedMessageTypesOnly() { + return consumerRecord -> { + try { + JSONObject consumed = XmlUtils.toJSONObject(consumerRecord.value()) + .getJSONObject(OdeAsn1Data.class.getSimpleName()); - /** - * While migrating to Spring Kafka the consumers provided from this factory will only consume (and ack) messages - * we support via the Spring Kafka implementation. All other messages will be handled by the Asn1DecodedDataRouter - * - * @return RecordFilterStrategy filter - */ - private static RecordFilterStrategy getFilterStrategySpringKafkaSupportedMessageTypesOnly() { - return consumerRecord -> { - try { - JSONObject consumed = XmlUtils.toJSONObject(consumerRecord.value()).getJSONObject(OdeAsn1Data.class.getSimpleName()); + J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( + consumed.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING) + .getJSONObject("MessageFrame").getInt("messageId")); - J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( - consumed.getJSONObject(AppContext.PAYLOAD_STRING) - .getJSONObject(AppContext.DATA_STRING) - .getJSONObject("MessageFrame") - .getInt("messageId") - ); + // Filter out all messages EXCEPT for MAP messages + return !J2735DSRCmsgID.MAPMessage.equals(messageId); + } catch (XmlUtils.XmlUtilsException e) { + log.warn("Unable to parse JSON object", e); + return false; + } catch (Exception e) { + log.warn("Failed to detect message ID", e); + return false; + } + }; + } - // Filter out all messages EXCEPT for MAP messages - return !J2735DSRCmsgID.MAPMessage.equals(messageId); - } catch (XmlUtils.XmlUtilsException e) { - log.warn("Unable to parse JSON object", e); - return false; - } catch (Exception e) { - log.warn("Failed to detect message ID", e); - return false; - } - }; + private Map getKafkaConsumerProperties() { + Map props = new HashMap<>(kafkaProperties.buildConsumerProperties()); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + props.putAll(this.odeKafkaProperties.getConfluent().buildConfluentProperties()); } + return props; + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java deleted file mode 100644 index ecfebe91a..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -package us.dot.its.jpo.ode.kafka; - -import org.apache.kafka.common.serialization.StringSerializer; -import org.springframework.boot.autoconfigure.kafka.KafkaProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.kafka.annotation.EnableKafka; -import org.springframework.kafka.core.DefaultKafkaProducerFactory; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.core.ProducerFactory; -import us.dot.its.jpo.ode.model.OdeObject; - -@EnableKafka -@Configuration -public class KafkaProducerConfig { - - private final KafkaProperties kafkaProperties; - private final OdeKafkaProperties odeKafkaProperties; - - public KafkaProducerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties odeKafkaProperties) { - this.kafkaProperties = kafkaProperties; - this.odeKafkaProperties = odeKafkaProperties; - } - - @Bean - public ProducerFactory producerFactory() { - var producerProps = kafkaProperties.buildProducerProperties(); - if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { - producerProps.put("ssl.endpoint.identification.algorithm", "https"); - producerProps.put("security.protocol", "SASL_SSL"); - producerProps.put("sasl.mechanism", "PLAIN"); - producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); - } - return new DefaultKafkaProducerFactory<>(producerProps); - } - - @Bean - public KafkaTemplate kafkaTemplate() { - return new KafkaTemplate<>(producerFactory()); - } - - @Bean - public ProducerFactory odeDataProducerFactory() { - var producerProps = kafkaProperties.buildProducerProperties(); - if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { - producerProps.put("ssl.endpoint.identification.algorithm", "https"); - producerProps.put("security.protocol", "SASL_SSL"); - producerProps.put("sasl.mechanism", "PLAIN"); - producerProps.put("sasl.jaas.config", odeKafkaProperties.getConfluent().getSaslJaasConfig()); - } - return new DefaultKafkaProducerFactory<>(producerProps, - new StringSerializer(), new XMLOdeObjectSerializer()); - } - - @Bean - public KafkaTemplate odeDataKafkaTemplate() { - return new KafkaTemplate<>(odeDataProducerFactory()); - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java index 6b85b0dde..8004dcad8 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodeMAPJSONListener.java @@ -10,7 +10,6 @@ import org.springframework.kafka.annotation.KafkaListener; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Component; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.Asn1Encoding; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; @@ -20,61 +19,62 @@ import us.dot.its.jpo.ode.uper.SupportedMessageType; import us.dot.its.jpo.ode.uper.UperUtil; -import java.util.Set; - +/** + * The Asn1DecodeMAPJSONListener class is a component designed to listen to messages from a + * specified Kafka topic, decode the ASN.1 encoded data from received JSON, and publish the decoded + * data to another Kafka topic. This class utilizes the @KafkaListener and @KafkaHandler annotations + * to process incoming Kafka messages. + */ @Slf4j @Component @KafkaListener(id = "Asn1DecodeMAPJSONListener", topics = "${ode.kafka.topics.raw-encoded-json.map}") public class Asn1DecodeMAPJSONListener { - private static final ObjectMapper objectMapper = new ObjectMapper(); - - private final String publishTopic; - private final KafkaTemplate kafkaTemplate; - private final Set disabledTopics; - - public Asn1DecodeMAPJSONListener(KafkaTemplate kafkaTemplate, - @Value("${ode.kafka.topics.asn1.decoder-input}") String publishTopic, - OdeKafkaProperties odeKafkaProperties) { - this.kafkaTemplate = kafkaTemplate; - this.publishTopic = publishTopic; - this.disabledTopics = odeKafkaProperties.getDisabledTopics(); - } + private static final ObjectMapper objectMapper = new ObjectMapper(); - @KafkaHandler - public void listen(String consumedData) throws JsonProcessingException, StartFlagNotFoundException { - log.debug("consumedData: {}", consumedData); - JSONObject rawMapJsonObject = new JSONObject(consumedData); + private final String publishTopic; + private final KafkaTemplate kafkaTemplate; - String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); - OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); + public Asn1DecodeMAPJSONListener(KafkaTemplate kafkaTemplate, + @Value("${ode.kafka.topics.asn1.decoder-input}") String publishTopic) { + this.kafkaTemplate = kafkaTemplate; + this.publishTopic = publishTopic; + } - Asn1Encoding unsecuredDataEncoding = new Asn1Encoding("unsecuredData", "MessageFrame", Asn1Encoding.EncodingRule.UPER); - metadata.addEncoding(unsecuredDataEncoding); + /** + * Processes consumed Kafka messages that contain ASN.1 encoded data within JSON format. + * This method decodes the message, extracts metadata and payload, and then publishes + * the decoded data to a specified Kafka topic. + * + * @param consumedData The raw JSON string consumed from the Kafka topic. This string + * is expected to contain ASN.1 encoded data that needs processing + * and further publication. + * @throws JsonProcessingException If there is an error in processing the JSON string. + * @throws StartFlagNotFoundException If the start flag is not found in the payload + * during header stripping. + */ + @KafkaHandler + public void listen(String consumedData) + throws JsonProcessingException, StartFlagNotFoundException { + log.debug("consumedData: {}", consumedData); + JSONObject rawMapJsonObject = new JSONObject(consumedData); - String payloadHexString = ((JSONObject) ((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString("bytes"); - payloadHexString = UperUtil.stripDot2Header(payloadHexString, SupportedMessageType.MAP.getStartFlag()); + String jsonStringMetadata = rawMapJsonObject.get("metadata").toString(); + OdeMapMetadata metadata = objectMapper.readValue(jsonStringMetadata, OdeMapMetadata.class); - OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + Asn1Encoding unsecuredDataEncoding = + new Asn1Encoding("unsecuredData", "MessageFrame", Asn1Encoding.EncodingRule.UPER); + metadata.addEncoding(unsecuredDataEncoding); - OdeAsn1Data data = new OdeAsn1Data(metadata, payload); - send(data); - } + String payloadHexString = + ((JSONObject) ((JSONObject) rawMapJsonObject.get("payload")).get("data")).getString( + "bytes"); + payloadHexString = + UperUtil.stripDot2Header(payloadHexString, SupportedMessageType.MAP.getStartFlag()); - private void send(OdeObject odeObject) { - if (disabledTopics.contains(publishTopic)) { - log.debug("Topic {} is disabled. Skipping sending message.", publishTopic); - return; - } - var future = kafkaTemplate.send(publishTopic, odeObject); + OdeAsn1Payload payload = new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - future.whenComplete((result, ex) -> { - if (ex != null) { - log.error(ex.getMessage(), ex); - } else { - log.debug("Successfully sent message to topic {} with offset {} on partition {}", - publishTopic, result.getRecordMetadata().offset(), result.getRecordMetadata().partition()); - } - }); - } + OdeAsn1Data data = new OdeAsn1Data(metadata, payload); + kafkaTemplate.send(publishTopic, data); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java index d44aabe76..49ad8d8c3 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.kafka.listeners; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.kafka.annotation.KafkaHandler; @@ -10,73 +11,84 @@ import org.springframework.stereotype.Component; import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeLogMetadata; import us.dot.its.jpo.ode.util.XmlUtils; -import java.util.Map; -import java.util.Set; - +/** + * The Asn1DecodedDataListener class is a component responsible for processing decoded ASN.1 data + * from Kafka topics. It listens to messages on a specified Kafka topic and handles the incoming + * data by processing and forwarding it to different topics based on specific criteria. + * + *

This listener is specifically designed to handle MAP data. Upon receiving a + * payload, it uses the {@link OdeMapDataCreatorHelper} to transform the payload and then determine + * the appropriate Kafka topic to forward the processed data. + * + *

The class utilizes Spring Kafka's annotation-driven listener configuration, + * allowing it to automatically consume messages from a configured Kafka topic. + */ @Slf4j @Component -@KafkaListener(id = "Asn1DecodedDataListener", topics = "${ode.kafka.topics.asn1.decoder-output}", containerFactory = "tempFilteringKafkaListenerContainerFactory") +@KafkaListener( + id = "Asn1DecodedDataListener", + topics = "${ode.kafka.topics.asn1.decoder-output}", + containerFactory = "tempFilteringKafkaListenerContainerFactory" +) public class Asn1DecodedDataListener { + private final String jsonMapTopic; + private final String pojoTxMapTopic; + private final KafkaTemplate kafkaTemplate; - private final String jsonMapTopic; - private final String pojoTxMapTopic; - private final KafkaTemplate kafkaTemplate; - private final Set disabledTopics; - - public Asn1DecodedDataListener(KafkaTemplate kafkaTemplate, - @Value("${ode.kafka.topics.pojo.tx-map}") String pojoTxMapTopic, - @Value("${ode.kafka.topics.json.map}") String jsonMapTopic, - OdeKafkaProperties odeKafkaProperties) { - this.kafkaTemplate = kafkaTemplate; - this.pojoTxMapTopic = pojoTxMapTopic; - this.jsonMapTopic = jsonMapTopic; - this.disabledTopics = odeKafkaProperties.getDisabledTopics(); - } - - @KafkaHandler - public void listenToMAPs(@Headers Map keys, @Payload String payload) { - log.debug("Key: {} payload: {}", keys, payload); - try { - String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(payload).toString(); + /** + * Constructs an instance of Asn1DecodedDataListener. + * + * @param kafkaTemplate the KafkaTemplate used for sending messages to Kafka topics. + * @param pojoTxMapTopic the name of the Kafka topic to which messages containing map transactions + * (mapTx) in POJO format are sent. + * @param jsonMapTopic the name of the Kafka topic where JSON-formatted messages are sent. + */ + public Asn1DecodedDataListener(KafkaTemplate kafkaTemplate, + @Value("${ode.kafka.topics.pojo.tx-map}") String pojoTxMapTopic, + @Value("${ode.kafka.topics.json.map}") String jsonMapTopic) { + this.kafkaTemplate = kafkaTemplate; + this.pojoTxMapTopic = pojoTxMapTopic; + this.jsonMapTopic = jsonMapTopic; + } - OdeLogMetadata.RecordType recordType = OdeLogMetadata.RecordType - .valueOf(XmlUtils.toJSONObject(payload) - .getJSONObject(OdeAsn1Data.class.getSimpleName()) - .getJSONObject(AppContext.METADATA_STRING) - .getString("recordType") - ); - if (recordType == OdeLogMetadata.RecordType.mapTx) { - log.debug("Publishing message with recordType: {} to {} ", recordType, pojoTxMapTopic); - send(odeMapData, pojoTxMapTopic); - } - - // Send all MAP data to OdeMapJson despite the record type - send(odeMapData, jsonMapTopic); - } catch (Exception e) { - log.error(e.getMessage(), e); - } - } + /** + * Processes the given Kafka message payload by transforming it into ODE MAP data and publishing + * it to appropriate Kafka topics based on its record type. Specifically, it publishes all + * transformed MAP data to a JSON topic and conditionally to a transaction-map topic if the record + * type is `mapTx`. + * + * @param keys the headers of the Kafka message, typically containing metadata for the + * message. + * @param payload the payload of the Kafka message, expected to be a string representation of the + * data that needs to be transformed and processed. + */ + @KafkaHandler + public void listenToMAPs(@Headers Map keys, @Payload String payload) { + log.debug("Key: {} payload: {}", keys, payload); + try { + String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(payload).toString(); - private void send(String odeMapData, String publishTopic) { - if (disabledTopics.contains(publishTopic)) { - log.debug("Topic {} is disabled. Skipping sending message.", publishTopic); - return; - } + OdeLogMetadata.RecordType recordType = OdeLogMetadata.RecordType + .valueOf(XmlUtils.toJSONObject(payload) + .getJSONObject(OdeAsn1Data.class.getSimpleName()) + .getJSONObject(AppContext.METADATA_STRING) + .getString("recordType") + ); + if (recordType == OdeLogMetadata.RecordType.mapTx) { + log.debug("Publishing message with recordType: {} to {} ", recordType, + pojoTxMapTopic); + kafkaTemplate.send(pojoTxMapTopic, odeMapData); + } - var future = kafkaTemplate.send(publishTopic, odeMapData); - future.whenComplete((result, ex) -> { - if (ex != null) { - log.error(ex.getMessage(), ex); - } else { - log.debug("Successfully sent message to topic {} with offset {} on partition {}", - publishTopic, result.getRecordMetadata().offset(), result.getRecordMetadata().partition()); - } - }); + // Send all MAP data to OdeMapJson despite the record type + kafkaTemplate.send(jsonMapTopic, odeMapData); + } catch (Exception e) { + log.error(e.getMessage(), e); } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java new file mode 100644 index 000000000..894d7f299 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java @@ -0,0 +1,19 @@ +package us.dot.its.jpo.ode.kafka.producer; + +/** + * DisabledTopicException is a custom exception that extends RuntimeException. + * It is thrown to indicate that a particular Kafka topic is disabled and cannot + * be used for publishing messages. This exception is typically used in Kafka + * producer configurations or interceptors to prevent message delivery to topics + * that are not allowed or are inactive. + * + *

The exception takes the name of the disabled topic as a parameter and constructs + * an informative error message indicating that the topic is disabled. + * + */ +public final class DisabledTopicException extends RuntimeException { + + public DisabledTopicException(String topic) { + super(String.format("Blocked attempt to send data to disabled topic %s", topic)); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java new file mode 100644 index 000000000..b5067a440 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java @@ -0,0 +1,66 @@ +package us.dot.its.jpo.ode.kafka.producer; + +import java.util.Map; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.producer.ProducerInterceptor; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; + +/** + * Through a set of disabled topics provided during initialization, this interceptor enforces that + * messages are not sent to these topics. If an attempt is made to send a message to a disabled + * topic, the interceptor throws a DisabledTopicException, effectively preventing the message from + * being dispatched. + * + *

The class also provides default logging behavior upon message acknowledgement and + * during interceptor closure. + * + * @param the type of the key for Kafka producer records + * @param the type of the value for Kafka producer records + */ +@Slf4j +public class DisabledTopicsProducerInterceptor + implements ProducerInterceptor { + + private final Set disabledTopics; + + /** + * Constructs a DisabledTopicsProducerInterceptor with a specified set of disabled topics. + * This set determines which topics are restricted from message dispatching. + * + * @param disabledTopics a set of topic names that are marked as disabled. Messages sent to these + * topics will result in a DisabledTopicException being thrown, ensuring + * they are not dispatched. + */ + protected DisabledTopicsProducerInterceptor(Set disabledTopics) { + this.disabledTopics = disabledTopics; + } + + @Override + public ProducerRecord onSend(ProducerRecord producerRecord) { + if (disabledTopics.contains(producerRecord.topic())) { + throw new DisabledTopicException(producerRecord.topic()); + } + return producerRecord; + } + + @Override + public void onAcknowledgement(RecordMetadata recordMetadata, Exception e) { + log.debug("Acknowledged message with offset {} on partition {}", recordMetadata.offset(), + recordMetadata.partition()); + if (e != null) { + log.error("Error acknowledging message", e); + } + } + + @Override + public void close() { + log.debug("Closing ProducerInterceptor"); + } + + @Override + public void configure(Map configs) { + // Default implementation + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java new file mode 100644 index 000000000..8590efe2f --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java @@ -0,0 +1,132 @@ +package us.dot.its.jpo.ode.kafka.producer; + +import java.util.Map; +import org.apache.kafka.common.serialization.StringSerializer; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.kafka.annotation.EnableKafka; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.XMLOdeObjectSerializer; +import us.dot.its.jpo.ode.model.OdeObject; + +/** + * KafkaProducerConfig is a configuration class for setting up Kafka producers with Spring Boot. + * This class utilizes the KafkaProperties and OdeKafkaProperties to define and construct the + * necessary producer factories and Kafka templates for producing messages to Kafka topics. + * + *

It provides configuration for two types of Kafka producer factories and templates: + * one for producing regular String messages and another for producing `OdeObject` messages + * serialized as XML. + * + *

This configuration is crucial for integrating with Kafka by providing + * necessary producer settings and managing producer instances. + */ +@EnableKafka +@Configuration +public class KafkaProducerConfig { + + private final KafkaProperties kafkaProperties; + private final OdeKafkaProperties odeKafkaProperties; + + /** + * Constructor for the KafkaProducerConfig class, which sets up the configuration for Kafka + * producers using provided Kafka properties. + * + * @param kafkaProperties the properties related to Kafka configuration as set up in the Spring + * environment, providing necessary configurations for creating Kafka + * producers. + * @param odeKafkaProperties the properties specific to the ODE Kafka setup, including custom + * configurations like Kafka type (e.g., CONFLUENT) and other + * specialized settings for integrating with the ODE infrastructure. + */ + public KafkaProducerConfig(KafkaProperties kafkaProperties, + OdeKafkaProperties odeKafkaProperties) { + this.kafkaProperties = kafkaProperties; + this.odeKafkaProperties = odeKafkaProperties; + } + + /** + * Creates a Kafka ProducerFactory configured for producing messages with String keys and String + * values. This factory sets up and manages the configuration needed for producing messages to + * Kafka topics using the properties defined in the application configuration. + * + * @return a ProducerFactory instance for creating Kafka producers with String key and value + * serializers. This includes any custom properties defined for Kafka producers, as well as + * additional settings for Confluent-based Kafka setups if applicable. + */ + @Bean + public ProducerFactory producerFactory() { + return new DefaultKafkaProducerFactory<>(buildProducerProperties()); + } + + /** + * Creates and returns a KafkaTemplate that allows for sending messages with String keys and + * String values to Kafka topics. This template is configured using the ProducerFactory instance + * provided by the producerFactory() method, ensuring that it is set up with the necessary + * serializers and additional properties defined in the application configuration. + * + * @return a KafkaTemplate instance configured for publishing messages to Kafka topics with String + * keys and values, facilitating message sending operations in Kafka. + */ + @Bean + public KafkaTemplate kafkaTemplate( + ProducerFactory producerFactory) { + var template = new KafkaTemplate<>(producerFactory); + + template.setProducerInterceptor( + new DisabledTopicsProducerInterceptor<>(this.odeKafkaProperties.getDisabledTopics())); + template.setProducerListener(new LoggingProducerListener<>()); + + return template; + } + + /** + * Creates a Kafka ProducerFactory specifically configured for handling messages with String keys + * and OdeObject values. This factory utilizes a custom XML serializer for OdeObjects, enabling + * proper serialization for Kafka message transmission. + * + * @return a ProducerFactory instance configured with String serializers for keys and a custom + * XMLOdeObjectSerializer for OdeObject values, using producer properties tailored to the + * application's Kafka and ODE settings. + */ + @Bean + public ProducerFactory odeDataProducerFactory() { + return new DefaultKafkaProducerFactory<>(buildProducerProperties(), + new StringSerializer(), new XMLOdeObjectSerializer()); + } + + /** + * Creates and returns a KafkaTemplate for sending messages with String keys and OdeObject values + * to Kafka topics. The template is configured using the ProducerFactory provided by the + * odeDataProducerFactory() method, ensuring it incorporates the necessary serializers and + * properties for proper message handling in the context of ODE and Kafka integration. + * + * @return a KafkaTemplate instance configured for handling messages with String keys and + * OdeObject values, enabling seamless message publication to Kafka topics within the + * application's messaging infrastructure. + */ + @Bean + public KafkaTemplate odeDataKafkaTemplate( + ProducerFactory producerFactory + ) { + var template = new KafkaTemplate<>(producerFactory); + template.setProducerInterceptor(new DisabledTopicsProducerInterceptor<>( + this.odeKafkaProperties.getDisabledTopics() + )); + template.setProducerListener(new LoggingProducerListener<>()); + + return template; + } + + private Map buildProducerProperties() { + var producerProps = kafkaProperties.buildProducerProperties(); + if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { + producerProps.putAll(this.odeKafkaProperties.getConfluent().buildConfluentProperties()); + } + return producerProps; + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java new file mode 100644 index 000000000..b74ad3211 --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java @@ -0,0 +1,43 @@ +package us.dot.its.jpo.ode.kafka.producer; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.springframework.kafka.support.ProducerListener; +import org.springframework.lang.Nullable; + +/** + * The LoggingProducerListener is a Kafka ProducerListener implementation that + * handles logging for Kafka producer events. + * + *

This class uses Slf4j for logging and should be added to Kafka producer + * configurations where logging of producer activity is required. + * + * @param the type of the key for Kafka producer records + * @param the type of the value for Kafka producer records + */ +@Slf4j +public final class LoggingProducerListener + implements ProducerListener { + + @Override + public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata) { + log.debug("Successfully produced key {} and value {} to topic {}", producerRecord.key(), + producerRecord.value(), producerRecord.topic()); + } + + @Override + public void onError( + ProducerRecord producerRecord, + @Nullable RecordMetadata recordMetadata, + Exception exception) { + if (exception instanceof DisabledTopicException) { + log.warn( + "Disabled topic exception encountered while producing key {} and value {} to topic {}", + producerRecord.key(), producerRecord.value(), producerRecord.topic()); + } else { + log.error("Failed to produce key {} and value {} to topic {}", producerRecord.key(), + producerRecord.value(), producerRecord.topic(), exception); + } + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java index b620ff2b2..4e26744fd 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/UdpHexDecoder.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.udp; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import us.dot.its.jpo.ode.model.OdeAsn1Data; @@ -28,185 +29,272 @@ import us.dot.its.jpo.ode.util.DateTimeUtils; import us.dot.its.jpo.ode.util.JsonUtils; -import java.net.DatagramPacket; - +/** + * The `UdpHexDecoder` class provides functionalities to decode UDP DatagramPackets into specific + * JSON representations based on the message type. It supports the extraction and conversion of the + * packet payloads into ASN.1 payloads for various message types such as MAP, SPAT, TIM, BSM, SSM, + * SRM, and PSM. + * + *

The class logs details about the packet's origin and ensures the payload contains the correct + * message type start flag. It provides methods to build JSON objects encapsulating metadata about + * each packet's origin, source, record type, and security information. + * + *

Note that this class cannot be instantiated. + */ @Slf4j public class UdpHexDecoder { - private UdpHexDecoder() { - throw new UnsupportedOperationException(); - } - - public static OdeAsn1Payload getPayloadHexString(DatagramPacket packet, SupportedMessageType msgType) throws InvalidPayloadException { - // extract the actual packet from the buffer - byte[] payload = packet.getData(); - if (payload == null) - throw new InvalidPayloadException("Payload is null"); - // convert bytes to hex string and verify identity - String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); - if (!payloadHexString.contains(msgType.getStartFlag())) - throw new InvalidPayloadException("Payload does not contain start flag"); - - log.debug("Full {} packet: {}", msgType, payloadHexString); - - payloadHexString = UperUtil.stripTrailingZeros(UperUtil.stripDot3Header(payloadHexString, msgType.getStartFlag())).toLowerCase(); - log.debug("Stripped {} packet: {}", msgType, payloadHexString); - - return new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); - } - - public static String buildJsonMapFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload mapPayload = getPayloadHexString(packet, SupportedMessageType.MAP); - OdeMapMetadata mapMetadata = new OdeMapMetadata(mapPayload); - - // Add header data for the decoding process - mapMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - mapMetadata.setOriginIp(senderIp); - mapMetadata.setMapSource(MapSource.RSU); - mapMetadata.setRecordType(RecordType.mapTx); - mapMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - mapMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(mapMetadata, mapPayload), false); + private UdpHexDecoder() { + throw new UnsupportedOperationException(); + } + + /** + * Extracts the payload from the given {@link DatagramPacket} and converts it into an + * {@link OdeAsn1Payload} object. The method validates that the payload contains the necessary + * start flag for the specified message type. + * + * @param packet the DatagramPacket containing the data + * @param msgType the type of message expected in the payload + * @return the extracted OdeAsn1Payload from the packet + * @throws InvalidPayloadException if the payload is null or does not contain the expected start + * flag + */ + public static OdeAsn1Payload getPayloadHexString(DatagramPacket packet, + SupportedMessageType msgType) throws InvalidPayloadException { + // extract the actual packet from the buffer + byte[] payload = packet.getData(); + if (payload == null) { + throw new InvalidPayloadException("Payload is null"); } - - public static String buildJsonSpatFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload spatPayload = getPayloadHexString(packet, SupportedMessageType.SPAT); - OdeSpatMetadata spatMetadata = new OdeSpatMetadata(spatPayload); - - // Add header data for the decoding process - spatMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - spatMetadata.setOriginIp(senderIp); - spatMetadata.setSpatSource(SpatSource.RSU); - spatMetadata.setRecordType(RecordType.spatTx); - spatMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - spatMetadata.setSecurityResultCode(SecurityResultCode.success); - - - return JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false); + // convert bytes to hex string and verify identity + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + if (!payloadHexString.contains(msgType.getStartFlag())) { + throw new InvalidPayloadException("Payload does not contain start flag"); } - public static String buildJsonTimFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload timPayload = getPayloadHexString(packet, SupportedMessageType.TIM); - OdeTimMetadata timMetadata = new OdeTimMetadata(timPayload); - - // Add header data for the decoding process - timMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - timMetadata.setOriginIp(senderIp); - timMetadata.setRecordType(RecordType.timMsg); - timMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - timMetadata.setSecurityResultCode(SecurityResultCode.success); - return JsonUtils.toJson(new OdeAsn1Data(timMetadata, timPayload), false); - } - - public static String buildJsonBsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - OdeAsn1Payload bsmPayload = getPayloadHexString(packet, SupportedMessageType.BSM); - OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); - - // Set BSM Metadata values that can be assumed from the UDP endpoint - bsmMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); - OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( - "unavailable", - "unavailable", - "unavailable", - "unavailable", - "unavailable"); - receivedMessageDetails.setRxSource(RxSource.RSU); - receivedMessageDetails.setLocationData(locationData); - bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); - - bsmMetadata.setOriginIp(senderIp); - bsmMetadata.setBsmSource(BsmSource.EV); - bsmMetadata.setRecordType(RecordType.bsmTx); - bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); - bsmMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false); - } - - public static String buildJsonSsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload ssmPayload = getPayloadHexString(packet, SupportedMessageType.SSM); - OdeSsmMetadata ssmMetadata = new OdeSsmMetadata(ssmPayload); - - // Add header data for the decoding process - ssmMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - ssmMetadata.setOriginIp(senderIp); - ssmMetadata.setSsmSource(SsmSource.RSU); - ssmMetadata.setRecordType(RecordType.ssmTx); - ssmMetadata.setRecordGeneratedBy(GeneratedBy.RSU); - ssmMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(ssmMetadata, ssmPayload), false); - } - - public static String buildJsonSrmFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload srmPayload = getPayloadHexString(packet, SupportedMessageType.SRM); - OdeSrmMetadata srmMetadata = new OdeSrmMetadata(srmPayload); - - // Add header data for the decoding process - srmMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - srmMetadata.setOriginIp(senderIp); - srmMetadata.setSrmSource(SrmSource.RSU); - srmMetadata.setRecordType(RecordType.srmTx); - srmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); - srmMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(srmMetadata, srmPayload), false); - } - - public static String buildJsonPsmFromPacket(DatagramPacket packet) throws InvalidPayloadException { - String senderIp = packet.getAddress().getHostAddress(); - int senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); - - // Create OdeMsgPayload and OdeLogMetadata objects and populate them - OdeAsn1Payload psmPayload = getPayloadHexString(packet, SupportedMessageType.PSM); - OdePsmMetadata psmMetadata = new OdePsmMetadata(psmPayload); - // Add header data for the decoding process - psmMetadata.setOdeReceivedAt(DateTimeUtils.now()); - - psmMetadata.setOriginIp(senderIp); - psmMetadata.setPsmSource(PsmSource.RSU); - psmMetadata.setRecordType(RecordType.psmTx); - psmMetadata.setRecordGeneratedBy(GeneratedBy.UNKNOWN); - psmMetadata.setSecurityResultCode(SecurityResultCode.success); - - return JsonUtils.toJson(new OdeAsn1Data(psmMetadata, psmPayload), false); - } + log.debug("Full {} packet: {}", msgType, payloadHexString); + + payloadHexString = UperUtil.stripTrailingZeros( + UperUtil.stripDot3Header(payloadHexString, msgType.getStartFlag())).toLowerCase(); + log.debug("Stripped {} packet: {}", msgType, payloadHexString); + + return new OdeAsn1Payload(HexUtils.fromHexString(payloadHexString)); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing a MAP + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the MAP data + * @return a JSON string representing the MAP message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonMapFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload mapPayload = getPayloadHexString(packet, SupportedMessageType.MAP); + OdeMapMetadata mapMetadata = new OdeMapMetadata(mapPayload); + + // Add header data for the decoding process + mapMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + mapMetadata.setOriginIp(senderIp); + mapMetadata.setMapSource(MapSource.RSU); + mapMetadata.setRecordType(RecordType.mapTx); + mapMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + mapMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(mapMetadata, mapPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing an SPAT + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the SPAT data + * @return a JSON string representing the SPAT message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonSpatFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload spatPayload = getPayloadHexString(packet, SupportedMessageType.SPAT); + OdeSpatMetadata spatMetadata = new OdeSpatMetadata(spatPayload); + + // Add header data for the decoding process + spatMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + spatMetadata.setOriginIp(senderIp); + spatMetadata.setSpatSource(SpatSource.RSU); + spatMetadata.setRecordType(RecordType.spatTx); + spatMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + spatMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(spatMetadata, spatPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing a TIM + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the TIM data + * @return a JSON string representing the TIM message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonTimFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload timPayload = getPayloadHexString(packet, SupportedMessageType.TIM); + OdeTimMetadata timMetadata = new OdeTimMetadata(timPayload); + + // Add header data for the decoding process + timMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + timMetadata.setOriginIp(senderIp); + timMetadata.setRecordType(RecordType.timMsg); + timMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + timMetadata.setSecurityResultCode(SecurityResultCode.success); + return JsonUtils.toJson(new OdeAsn1Data(timMetadata, timPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing a BSM + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the BSM data + * @return a JSON string representing the BSM message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonBsmFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + OdeAsn1Payload bsmPayload = getPayloadHexString(packet, SupportedMessageType.BSM); + OdeBsmMetadata bsmMetadata = new OdeBsmMetadata(bsmPayload); + + // Set BSM Metadata values that can be assumed from the UDP endpoint + bsmMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + ReceivedMessageDetails receivedMessageDetails = new ReceivedMessageDetails(); + OdeLogMsgMetadataLocation locationData = new OdeLogMsgMetadataLocation( + "unavailable", + "unavailable", + "unavailable", + "unavailable", + "unavailable"); + receivedMessageDetails.setRxSource(RxSource.RSU); + receivedMessageDetails.setLocationData(locationData); + bsmMetadata.setReceivedMessageDetails(receivedMessageDetails); + + bsmMetadata.setOriginIp(senderIp); + bsmMetadata.setBsmSource(BsmSource.EV); + bsmMetadata.setRecordType(RecordType.bsmTx); + bsmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); + bsmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(bsmMetadata, bsmPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing an SSM + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the SSM data + * @return a JSON string representing the SSM message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonSsmFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload ssmPayload = getPayloadHexString(packet, SupportedMessageType.SSM); + OdeSsmMetadata ssmMetadata = new OdeSsmMetadata(ssmPayload); + + // Add header data for the decoding process + ssmMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + ssmMetadata.setOriginIp(senderIp); + ssmMetadata.setSsmSource(SsmSource.RSU); + ssmMetadata.setRecordType(RecordType.ssmTx); + ssmMetadata.setRecordGeneratedBy(GeneratedBy.RSU); + ssmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(ssmMetadata, ssmPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing an SRM + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the SRM data + * @return a JSON string representing the SRM message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonSrmFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload srmPayload = getPayloadHexString(packet, SupportedMessageType.SRM); + OdeSrmMetadata srmMetadata = new OdeSrmMetadata(srmPayload); + + // Add header data for the decoding process + srmMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + srmMetadata.setOriginIp(senderIp); + srmMetadata.setSrmSource(SrmSource.RSU); + srmMetadata.setRecordType(RecordType.srmTx); + srmMetadata.setRecordGeneratedBy(GeneratedBy.OBU); + srmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(srmMetadata, srmPayload), false); + } + + /** + * Converts the data from the given {@link DatagramPacket} into a JSON string representing a PSM + * message. It extracts metadata and payload, then structures them into a JSON format. + * + * @param packet the DatagramPacket containing the PSM data + * @return a JSON string representing the PSM message + * @throws InvalidPayloadException if the payload extraction fails + */ + public static String buildJsonPsmFromPacket(DatagramPacket packet) + throws InvalidPayloadException { + String senderIp = packet.getAddress().getHostAddress(); + int senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); + + // Create OdeMsgPayload and OdeLogMetadata objects and populate them + OdeAsn1Payload psmPayload = getPayloadHexString(packet, SupportedMessageType.PSM); + OdePsmMetadata psmMetadata = new OdePsmMetadata(psmPayload); + // Add header data for the decoding process + psmMetadata.setOdeReceivedAt(DateTimeUtils.now()); + + psmMetadata.setOriginIp(senderIp); + psmMetadata.setPsmSource(PsmSource.RSU); + psmMetadata.setRecordType(RecordType.psmTx); + psmMetadata.setRecordGeneratedBy(GeneratedBy.UNKNOWN); + psmMetadata.setSecurityResultCode(SecurityResultCode.success); + + return JsonUtils.toJson(new OdeAsn1Data(psmMetadata, psmPayload), false); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index 2773fbc4b..92ba00d9e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -1,49 +1,77 @@ package us.dot.its.jpo.ode.udp.bsm; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -import java.net.DatagramPacket; - +/** + * The BsmReceiver class is responsible for receiving UDP packets containing Basic Safety Message + * (BSM) data, decoding the packets, and publishing the decoded message to a specified Kafka topic. + * It extends the AbstractUdpReceiverPublisher, leveraging its capabilities to receive UDP packets + * asynchronously. + */ @Slf4j public class BsmReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher bsmPublisher; - private final String publishTopic; - - public BsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - - this.publishTopic = publishTopic; - this.bsmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } - - @Override - public void run() { - log.debug("BSM UDP Receiver Service started."); - - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP BSM packets..."); - this.socket.receive(packet); - if (packet.getLength() > 0) { - String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - if (bsmJson != null) { - bsmPublisher.publish(publishTopic, bsmJson); - } - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); + private final KafkaTemplate bsmPublisher; + private final String publishTopic; + + /** + * Constructs a BsmReceiver object that is responsible for receiving UDP packets, decoding Basic + * Safety Message (BSM) data, and publishing the decoded message to a specified Kafka topic. + * + * @param receiverProperties properties that configure the UDP receiver, including the port and + * buffer size. + * @param template KafkaTemplate used for sending messages to the Kafka broker. + * @param publishTopic the Kafka topic to which the decoded BSM data should be published. + */ + public BsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, + KafkaTemplate template, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + + this.publishTopic = publishTopic; + this.bsmPublisher = template; + } + + @Override + public void run() { + log.debug("BSM UDP Receiver Service started."); + + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP BSM packets..."); + this.socket.receive(packet); + if ((packet.getLength() <= 0)) { + log.debug("Skipping empty payload"); + continue; + } + + String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); + if (bsmJson != null) { + log.debug("Publishing String data to {}", publishTopic); + + var sendResult = bsmPublisher.send(publishTopic, bsmJson); + sendResult.whenCompleteAsync((result, error) -> { + if (error != null) { + log.error("Error sending BSM to Kafka", error); } - } while (!isStopped()); - } + }); + } + + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java index 097fdbb07..ae7da8093 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/controller/UdpServicesController.java @@ -4,7 +4,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.stereotype.Controller; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.bsm.BsmReceiver; import us.dot.its.jpo.ode.udp.generic.GenericReceiver; @@ -22,22 +21,41 @@ @Slf4j public class UdpServicesController { - @Autowired - public UdpServicesController(UDPReceiverProperties udpProps, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics, KafkaTemplate kafkaTemplate) { - super(); + /** + * Constructs a UdpServicesController to manage UDP receiver services for different message + * types. + * + * @param udpProps Properties containing configuration for each UDP receiver. + * @param rawEncodedJsonTopics Topics to which the decoded messages will be published via Kafka. + * @param kafkaTemplate Template to facilitate sending messages to Kafka topics. + */ + @Autowired + public UdpServicesController(UDPReceiverProperties udpProps, + RawEncodedJsonTopics rawEncodedJsonTopics, + KafkaTemplate kafkaTemplate) { + super(); - ServiceManager rm = new ServiceManager(new UdpServiceThreadFactory("UdpReceiverManager")); - log.debug("Starting UDP receiver services..."); + ServiceManager serviceManager = new ServiceManager( + new UdpServiceThreadFactory("UdpReceiverManager")); + log.debug("Starting UDP receiver services..."); - rm.submit(new BsmReceiver(udpProps.getBsm(), odeKafkaProperties, rawEncodedJsonTopics.getBsm())); - rm.submit(new TimReceiver(udpProps.getTim(), odeKafkaProperties, rawEncodedJsonTopics.getTim())); - rm.submit(new SsmReceiver(udpProps.getSsm(), odeKafkaProperties, rawEncodedJsonTopics.getSsm())); - rm.submit(new SrmReceiver(udpProps.getSrm(), odeKafkaProperties, rawEncodedJsonTopics.getSrm())); - rm.submit(new SpatReceiver(udpProps.getSpat(), odeKafkaProperties, rawEncodedJsonTopics.getSpat())); - rm.submit(new MapReceiver(udpProps.getMap(), kafkaTemplate, rawEncodedJsonTopics.getMap())); - rm.submit(new PsmReceiver(udpProps.getPsm(), odeKafkaProperties, rawEncodedJsonTopics.getPsm())); - rm.submit(new GenericReceiver(udpProps.getGeneric(), odeKafkaProperties, rawEncodedJsonTopics)); + serviceManager.submit( + new BsmReceiver(udpProps.getBsm(), kafkaTemplate, rawEncodedJsonTopics.getBsm())); + serviceManager.submit( + new TimReceiver(udpProps.getTim(), kafkaTemplate, rawEncodedJsonTopics.getTim())); + serviceManager.submit( + new SsmReceiver(udpProps.getSsm(), kafkaTemplate, rawEncodedJsonTopics.getSsm())); + serviceManager.submit( + new SrmReceiver(udpProps.getSrm(), kafkaTemplate, rawEncodedJsonTopics.getSrm())); + serviceManager.submit( + new SpatReceiver(udpProps.getSpat(), kafkaTemplate, rawEncodedJsonTopics.getSpat())); + serviceManager.submit( + new MapReceiver(udpProps.getMap(), kafkaTemplate, rawEncodedJsonTopics.getMap())); + serviceManager.submit( + new PsmReceiver(udpProps.getPsm(), kafkaTemplate, rawEncodedJsonTopics.getPsm())); + serviceManager.submit( + new GenericReceiver(udpProps.getGeneric(), kafkaTemplate, rawEncodedJsonTopics)); - log.debug("UDP receiver services started."); - } + log.debug("UDP receiver services started."); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index 86658d093..1e53b192f 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -1,111 +1,140 @@ package us.dot.its.jpo.ode.udp.generic; +import io.netty.handler.codec.UnsupportedMessageTypeException; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; import us.dot.its.jpo.ode.uper.UperUtil; -import java.net.DatagramPacket; - +/** + * GenericReceiver is a class that listens for UDP packets and processes them based on the + * determined message type. It extends AbstractUdpReceiverPublisher to take advantage of the + * runnable interface for running the receiver service in a separate thread. + * + *

The class is designed to handle all {@link us.dot.its.jpo.ode.uper.SupportedMessageType} + * message types encoded in UDP packets such as and routes them to the appropriate Kafka topic. + */ @Slf4j public class GenericReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher publisher; - private final RawEncodedJsonTopics rawEncodedJsonTopics; + private final KafkaTemplate publisher; + private final RawEncodedJsonTopics rawEncodedJsonTopics; - public GenericReceiver(UDPReceiverProperties.ReceiverProperties props, OdeKafkaProperties odeKafkaProperties, RawEncodedJsonTopics rawEncodedJsonTopics) { - super(props.getReceiverPort(), props.getBufferSize()); + /** + * Constructs a new GenericReceiver with the specified properties, Kafka template, and raw encoded + * JSON topics. + * + * @param props the receiver properties containing configuration settings such as + * port and buffer size + * @param kafkaTemplate the KafkaTemplate used for publishing messages + * @param rawEncodedJsonTopics the configuration object containing the topics used to publish + * messages + */ + public GenericReceiver(ReceiverProperties props, KafkaTemplate kafkaTemplate, + RawEncodedJsonTopics rawEncodedJsonTopics) { + super(props.getReceiverPort(), props.getBufferSize()); - this.publisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - this.rawEncodedJsonTopics = rawEncodedJsonTopics; - } + this.publisher = kafkaTemplate; + this.rawEncodedJsonTopics = rawEncodedJsonTopics; + } - @Override - public void run() { - log.debug("Generic UDP Receiver Service started."); + @Override + public void run() { + log.debug("Generic UDP Receiver Service started."); - byte[] buffer; - do { - buffer = new byte[bufferSize]; - // packet should be recreated on each loop to prevent latent data in buffer - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - try { - log.debug("Waiting for Generic UDP packets..."); - socket.receive(packet); - byte[] payload = packet.getData(); - if ((packet.getLength() <= 0) || (payload == null)) { - log.debug("Skipping empty payload"); - continue; - } + byte[] buffer; + do { + buffer = new byte[bufferSize]; + // packet should be recreated on each loop to prevent latent data in buffer + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + try { + log.debug("Waiting for Generic UDP packets..."); + socket.receive(packet); + byte[] payload = packet.getData(); + if ((packet.getLength() <= 0) || (payload == null)) { + log.debug("Skipping empty payload"); + continue; + } - senderIp = packet.getAddress().getHostAddress(); - senderPort = packet.getPort(); - log.debug("Packet received from {}:{}", senderIp, senderPort); + senderIp = packet.getAddress().getHostAddress(); + senderPort = packet.getPort(); + log.debug("Packet received from {}:{}", senderIp, senderPort); - String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); - log.debug("Raw Payload {}", payloadHexString); + String payloadHexString = HexUtils.toHexString(payload).toLowerCase(); + log.debug("Raw Payload {}", payloadHexString); - String messageType = UperUtil.determineHexPacketType(payloadHexString); + String messageType = UperUtil.determineHexPacketType(payloadHexString); + routeMessageByMessageType(messageType, packet); - log.debug("Detected Message Type {}", messageType); + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (UnsupportedMessageTypeException e) { + log.error("Unsupported Message Type", e); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } - switch (messageType) { - case "MAP" -> { - String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); - log.debug("Sending Data to Topic {}", mapJson); - if (mapJson != null) { - publisher.publish(rawEncodedJsonTopics.getMap(), mapJson); - } - } - case "SPAT" -> { - String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); - if (spatJson != null) { - publisher.publish(rawEncodedJsonTopics.getSpat(), spatJson); - } - } - case "TIM" -> { - String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); - if (timJson != null) { - publisher.publish(rawEncodedJsonTopics.getTim(), timJson); - } - } - case "BSM" -> { - String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); - if (bsmJson != null) { - publisher.publish(rawEncodedJsonTopics.getBsm(), bsmJson); - } - } - case "SSM" -> { - String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - if (ssmJson != null) { - publisher.publish(rawEncodedJsonTopics.getSsm(), ssmJson); - } - } - case "SRM" -> { - String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); - if (srmJson != null) { - publisher.publish(rawEncodedJsonTopics.getSrm(), srmJson); - } - } - case "PSM" -> { - String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); - if (psmJson != null) { - publisher.publish(rawEncodedJsonTopics.getPsm(), psmJson); - } - } - default -> log.debug("Unknown Message Type"); - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); + private void routeMessageByMessageType( + String messageType, + DatagramPacket packet + ) throws InvalidPayloadException, UnsupportedMessageTypeException { + log.debug("Detected Message Type {}", messageType); + switch (messageType) { + case "MAP" -> { + String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); + log.debug("Sending Data to Topic {}", mapJson); + if (mapJson != null) { + publisher.send(rawEncodedJsonTopics.getMap(), mapJson); + } + } + case "SPAT" -> { + String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); + if (spatJson != null) { + publisher.send(rawEncodedJsonTopics.getSpat(), spatJson); + } + } + case "TIM" -> { + String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); + if (timJson != null) { + publisher.send(rawEncodedJsonTopics.getTim(), timJson); + } + } + case "BSM" -> { + String bsmJson = UdpHexDecoder.buildJsonBsmFromPacket(packet); + if (bsmJson != null) { + publisher.send(rawEncodedJsonTopics.getBsm(), bsmJson); + } + } + case "SSM" -> { + String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); + if (ssmJson != null) { + publisher.send(rawEncodedJsonTopics.getSsm(), ssmJson); + } + } + case "SRM" -> { + String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); + if (srmJson != null) { + publisher.send(rawEncodedJsonTopics.getSrm(), srmJson); + } + } + case "PSM" -> { + String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); + if (psmJson != null) { + publisher.send(rawEncodedJsonTopics.getPsm(), psmJson); + } + } + default -> throw new UnsupportedMessageTypeException(messageType); } + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index ab70c7269..ce828d60b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -1,50 +1,75 @@ package us.dot.its.jpo.ode.udp.map; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; -import java.net.DatagramPacket; - +/** + * The MapReceiver class is responsible for receiving UDP packets, decoding + * them, and publishing the decoded JSON map to a specified Kafka topic. + * It extends the {@link AbstractUdpReceiverPublisher} class to leverage UDP + * receiving capabilities. + * + *

MapReceiver listens on a specified port for incoming UDP packets encapsulating + * map data, and decodes these packets. Upon successful decoding, the map data is published + * to a Kafka topic using KafkaTemplate. + */ @Slf4j public class MapReceiver extends AbstractUdpReceiverPublisher { - KafkaTemplate kafkaTemplate; - private final String publishTopic; + KafkaTemplate kafkaTemplate; + private final String publishTopic; - public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.kafkaTemplate = kafkaTemplate; - this.publishTopic = publishTopic; - } + /** + * Constructs a new MapReceiver instance to receive UDP packets, decode them, + * and publish the decoded map data to a specified Kafka topic. + * + * @param receiverProperties The properties that define the UDP receiver + * configuration, including the port on which to + * listen and the buffer size for incoming packets. + * @param kafkaTemplate The KafkaTemplate instance used to send messages + * to the Kafka topic. + * @param publishTopic The topic to which decoded map data should be + * published. + */ + public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, + KafkaTemplate kafkaTemplate, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + this.kafkaTemplate = kafkaTemplate; + this.publishTopic = publishTopic; + } - @Override - public void run() { - log.debug("Map UDP Receiver Service started."); + @Override + public void run() { + log.debug("Map UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP Map packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); - if (mapJson != null) { - kafkaTemplate.send(publishTopic, mapJson); - } - } else { - log.debug("Ignoring empty packet from {}", packet.getSocketAddress()); - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP Map packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String mapJson = UdpHexDecoder.buildJsonMapFromPacket(packet); + if (mapJson != null) { + kafkaTemplate.send(publishTopic, mapJson); + } + } else { + log.debug("Ignoring empty packet from {}", packet.getSocketAddress()); + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index c0ed9c7c4..7915ceb07 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -1,49 +1,71 @@ package us.dot.its.jpo.ode.udp.psm; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; - -import java.net.DatagramPacket; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; +/** + * The PsmReceiver class extends AbstractUdpReceiverPublisher and is responsible for receiving + * UDP packets containing PSM (Position & Status Message) data, decoding them from their + * hex representation to JSON format, and then publishing the JSON data to a Kafka topic. + * + *

+ * The class utilizes a KafkaTemplate for publishing messages and a configurable topic + * name where the decoded PSM JSON messages are sent. + */ @Slf4j public class PsmReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher psmPublisher; - private final String publishTopic; + private final KafkaTemplate psmPublisher; + private final String publishTopic; - public PsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + /** + * Constructs a PsmReceiver object that listens for UDP packets containing + * Position & Status Message (PSM) data, decodes them, and publishes the decoded + * JSON data to a specified Kafka topic. + * + * @param receiverProperties The properties containing configuration details such as the port to + * listen on and buffer size. + * @param kafkaTemplate The KafkaTemplate used to publish messages to a Kafka topic. + * @param publishTopic The name of the Kafka topic to which decoded PSM JSON messages + * should be published. + */ + public PsmReceiver(ReceiverProperties receiverProperties, + KafkaTemplate kafkaTemplate, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.publishTopic = publishTopic; - this.psmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } + this.publishTopic = publishTopic; + this.psmPublisher = kafkaTemplate; + } - @Override - public void run() { - log.debug("PSM UDP Receiver Service started."); + @Override + public void run() { + log.debug("PSM UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP PSM packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); - if (psmJson != null) { - psmPublisher.publish(this.publishTopic, psmJson); - } - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP PSM packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String psmJson = UdpHexDecoder.buildJsonPsmFromPacket(packet); + if (psmJson != null) { + psmPublisher.send(publishTopic, psmJson); + } + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index 78f24ecad..d5d6f0f65 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -1,49 +1,70 @@ package us.dot.its.jpo.ode.udp.spat; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; - -import java.net.DatagramPacket; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; +/** + * The SpatReceiver class is responsible for receiving UDP packets containing SPaT (Signal Phase and + * Timing) data, decoding these packets, and publishing the resulting JSON string to a specified + * Kafka topic. + * + *

+ * This class extends the AbstractUdpReceiverPublisher, allowing it to run as a separate thread and + * handle incoming UDP packets. It utilizes a Kafka template to publish decoded data. + */ @Slf4j public class SpatReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher spatPublisher; - private final String publishTopic; + private final KafkaTemplate spatPublisher; + private final String publishTopic; - public SpatReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + /** + * Constructs a SpatReceiver object that is responsible for receiving UDP packets containing SPaT + * (Signal Phase and Timing) data, decoding these packets, and publishing the resulting JSON + * string to a specified Kafka topic. + * + * @param receiverProperties the properties for the receiver including the port and buffer size + * @param kafkaTemplate the Kafka template used for publishing the decoded SPaT data + * @param publishTopic the Kafka topic to which the decoded SPaT data will be published + */ + public SpatReceiver( + ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, + String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.publishTopic = publishTopic; - this.spatPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } + this.publishTopic = publishTopic; + this.spatPublisher = kafkaTemplate; + } - @Override - public void run() { - log.debug("SPaT UDP Receiver Service started."); + @Override + public void run() { + log.debug("SPaT UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP SPaT packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); - if (spatJson != null) { - spatPublisher.publish(this.publishTopic, spatJson); - } - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP SPaT packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String spatJson = UdpHexDecoder.buildJsonSpatFromPacket(packet); + if (spatJson != null) { + spatPublisher.send(publishTopic, spatJson); + } + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index dba63b8c1..5fe8f7257 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -1,49 +1,72 @@ package us.dot.its.jpo.ode.udp.srm; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; - -import java.net.DatagramPacket; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; +/** + * SrmReceiver is responsible for receiving UDP packets containing SRM (Signal Request Message) + * data, decoding them, and publishing the decoded messages to a specified Kafka topic. + * + *

+ * This class extends the AbstractUdpReceiverPublisher and overrides its run method to implement + * the logic for receiving packets, processing them, and sending the result to Kafka. + * + *

+ * It utilizes a KafkaTemplate for sending messages to Kafka and uses a DatagramSocket to listen + * for incoming UDP packets on a specified port. + */ @Slf4j public class SrmReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher srmPublisher; - private final String publishTopic; + private final KafkaTemplate srmPublisher; + private final String publishTopic; - public SrmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + /** + * Constructs an instance of SrmReceiver which is responsible for receiving UDP packets + * carrying SRM data, decoding them, and publishing the results to a Kafka topic. + * + * @param receiverProperties the properties for configuring the UDP receiver, including port + * and buffer size. + * @param kafkaTemplate the KafkaTemplate to be used for publishing decoded messages to Kafka. + * @param publishTopic the Kafka topic to which the decoded SRM messages will be published. + */ + public SrmReceiver(ReceiverProperties receiverProperties, + KafkaTemplate kafkaTemplate, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.publishTopic = publishTopic; - this.srmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } + this.publishTopic = publishTopic; + this.srmPublisher = kafkaTemplate; + } - @Override - public void run() { - log.debug("SRM UDP Receiver Service started."); + @Override + public void run() { + log.debug("SRM UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP SRM packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); - if (srmJson != null) { - srmPublisher.publish(publishTopic, srmJson); - } - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP SRM packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String srmJson = UdpHexDecoder.buildJsonSrmFromPacket(packet); + if (srmJson != null) { + srmPublisher.send(publishTopic, srmJson); + } + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index d4dd8e164..e6abdd536 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -1,49 +1,64 @@ package us.dot.its.jpo.ode.udp.ssm; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; - -import java.net.DatagramPacket; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; +/** + * The SsmReceiver class is responsible for receiving UDP packets and publishing them as JSON + * messages to a specified Kafka topic. It extends the functionality of AbstractUdpReceiverPublisher + * to handle UDP packet reception and decoding. + */ @Slf4j public class SsmReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher ssmPublisher; - private final String publishTopic; + private final KafkaTemplate ssmPublisher; + private final String publishTopic; - public SsmReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); + /** + * Constructs an SsmReceiver to handle UDP packets and publish them to a specified Kafka topic. + * + * @param receiverProperties Properties object containing the receiver configuration like port and + * buffer size. + * @param kafkaTemplate Kafka template used to send messages to a Kafka topic. + * @param publishTopic The Kafka topic to which the decoded UDP packets will be published. + */ + public SsmReceiver(ReceiverProperties receiverProperties, + KafkaTemplate kafkaTemplate, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - this.publishTopic = publishTopic; - this.ssmPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } + this.publishTopic = publishTopic; + this.ssmPublisher = kafkaTemplate; + } - @Override - public void run() { - log.debug("SSM UDP Receiver Service started."); + @Override + public void run() { + log.debug("SSM UDP Receiver Service started."); - byte[] buffer = new byte[bufferSize]; - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); - do { - try { - log.debug("Waiting for UDP SSM packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { - String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); - if (ssmJson != null) { - ssmPublisher.publish(this.publishTopic, ssmJson); - } - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + byte[] buffer = new byte[bufferSize]; + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP SSM packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String ssmJson = UdpHexDecoder.buildJsonSsmFromPacket(packet); + if (ssmJson != null) { + ssmPublisher.send(publishTopic, ssmJson); + } + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 96b599222..701e9c5b0 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -1,55 +1,71 @@ package us.dot.its.jpo.ode.udp.tim; +import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; -import us.dot.its.jpo.ode.coder.StringPublisher; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import org.springframework.kafka.core.KafkaTemplate; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; -import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; - -import java.net.DatagramPacket; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; +/** + * The TimReceiver class extends the AbstractUdpReceiverPublisher and is responsible + * for receiving UDP packets containing TIM (Traveler Information Message) data. + * Upon receiving a packet, it decodes the TIM data and forwards it to a specified + * Kafka topic using a KafkaTemplate. + */ @Slf4j public class TimReceiver extends AbstractUdpReceiverPublisher { - private final StringPublisher timPublisher; - private final String publishTopic; - - public TimReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, OdeKafkaProperties odeKafkaProperties, String publishTopic) { - super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - - this.publishTopic = publishTopic; - this.timPublisher = new StringPublisher(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); - } - - @Override - public void run() { - log.debug("TIM UDP Receiver Service started."); + private final KafkaTemplate timPublisher; + private final String publishTopic; - byte[] buffer = new byte[bufferSize]; + /** + * Constructs a TimReceiver for receiving UDP packets and forwarding TIM + * (Traveler Information Message) data to a Kafka topic. + * + * @param receiverProperties contains configuration properties such as + * receiver port and buffer size needed for establishing the UDP receiver. + * @param kafkaTemplate the KafkaTemplate used for sending the TIM data to the specified + * Kafka topic after decoding. + * @param publishTopic the name of the Kafka topic to which the decoded TIM data should + * be published. + */ + public TimReceiver(ReceiverProperties receiverProperties, + KafkaTemplate kafkaTemplate, String publishTopic) { + super(receiverProperties.getReceiverPort(), receiverProperties.getBufferSize()); - DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + this.publishTopic = publishTopic; + this.timPublisher = kafkaTemplate; + } - do { - try { - log.debug("Waiting for UDP TIM packets..."); - socket.receive(packet); - if (packet.getLength() > 0) { + @Override + public void run() { + log.debug("TIM UDP Receiver Service started."); - String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); - if (timJson != null) { - timPublisher.publish(publishTopic, timJson); - } + byte[] buffer = new byte[bufferSize]; - } - } catch (InvalidPayloadException e) { - log.error("Error decoding packet", e); - } catch (Exception e) { - log.error("Error receiving packet", e); - } - } while (!isStopped()); - } + DatagramPacket packet = new DatagramPacket(buffer, buffer.length); + do { + try { + log.debug("Waiting for UDP TIM packets..."); + socket.receive(packet); + if (packet.getLength() > 0) { + String timJson = UdpHexDecoder.buildJsonTimFromPacket(packet); + if (timJson != null) { + timPublisher.send(publishTopic, timJson); + } + } + } catch (DisabledTopicException e) { + log.warn(e.getMessage()); + } catch (InvalidPayloadException e) { + log.error("Error decoding packet", e); + } catch (Exception e) { + log.error("Error receiving packet", e); + } + } while (!isStopped()); + } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java index b5c8f49d7..0b8f1d7e1 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/uper/UperUtil.java @@ -1,5 +1,6 @@ package us.dot.its.jpo.ode.uper; +import java.util.HashMap; import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.json.JSONObject; @@ -7,168 +8,214 @@ import us.dot.its.jpo.ode.util.JsonUtils; import us.dot.its.jpo.ode.util.JsonUtils.JsonUtilsException; -import java.util.HashMap; - +/** + * Utility class for handling and manipulating hexadecimal strings representing network packet data, + * particularly those adhering to IEEE 1609.2 and 1609.3 standards. + */ @Slf4j public class UperUtil { - private UperUtil() { - throw new UnsupportedOperationException(); + private UperUtil() { + throw new UnsupportedOperationException(); + } + + /** + * Strips the IEEE 1609.2 security header (if it exists) and returns the payload from a given + * hexadecimal string. The method searches for a specified start flag that indicates the beginning + * of the payload. + * + * @param hexString the input hexadecimal string from which the IEEE 1609.2 security header + * needs to be stripped. + * @param payloadStartFlag the start flag indicating the beginning of the payload. + * + * @return a string representing the payload without the IEEE 1609.2 security header, if the start + * flag is found. + * + * @throws StartFlagNotFoundException if the specified start flag is not found within the + * hexadecimal string. + */ + public static String stripDot2Header(String hexString, String payloadStartFlag) + throws StartFlagNotFoundException { + hexString = hexString.toLowerCase(); + int startIndex = findValidStartFlagLocation(hexString, payloadStartFlag); + if (startIndex == -1) { + throw new StartFlagNotFoundException( + "Start flag" + payloadStartFlag + " not found in message"); } - - // Strips the IEEE 1609.2 security header (if it exists) and returns the payload - public static String stripDot2Header(String hexString, String payloadStartFlag) throws StartFlagNotFoundException { - hexString = hexString.toLowerCase(); - int startIndex = findValidStartFlagLocation(hexString, payloadStartFlag); - if (startIndex == -1) - throw new StartFlagNotFoundException("Start flag" + payloadStartFlag + " not found in message"); - return stripTrailingZeros(hexString.substring(startIndex)); + return stripTrailingZeros(hexString.substring(startIndex)); + } + + /** + * Strips the 1609.3 and unsigned 1609.2 headers if they are present. Will return the payload with + * a signed 1609.2 header if it is present. Otherwise, returns just the payload. + */ + public static byte[] stripDot3Header(byte[] packet, HashMap msgStartFlags) { + + String hexString = HexUtils.toHexString(packet); + String hexPacketParsed = ""; + + for (String startFlag : msgStartFlags.values()) { + int payloadStartIndex = findValidStartFlagLocation(hexString, startFlag); + if (payloadStartIndex == -1) { + continue; + } + + String headers = hexString.substring(0, payloadStartIndex); + String payload = hexString.substring(payloadStartIndex); + + // Look for the index of the start flag of a signed 1609.2 header, if one exists + int signedDot2StartIndex = headers.indexOf("038100"); + if (signedDot2StartIndex == -1) { + hexPacketParsed = payload; + } else { + hexPacketParsed = headers.substring(signedDot2StartIndex) + payload; + } + break; } - /* - * Strips the 1609.3 and unsigned 1609.2 headers if they are present. - * Will return the payload with a signed 1609.2 header if it is present. - * Otherwise, returns just the payload. - */ - public static byte[] stripDot3Header(byte[] packet, HashMap msgStartFlags) { - - String hexString = HexUtils.toHexString(packet); - String hexPacketParsed = ""; - - for (String start_flag : msgStartFlags.values()) { - int payloadStartIndex = findValidStartFlagLocation(hexString, start_flag); - if (payloadStartIndex == -1){ - continue; - } - - String headers = hexString.substring(0, payloadStartIndex); - String payload = hexString.substring(payloadStartIndex); - - // Look for the index of the start flag of a signed 1609.2 header, if one exists - int signedDot2StartIndex = headers.indexOf("038100"); - if (signedDot2StartIndex == -1) - hexPacketParsed = payload; - else - hexPacketParsed = headers.substring(signedDot2StartIndex) + payload; - break; - } - - if (hexPacketParsed.isEmpty()) { - hexPacketParsed = hexString; - log.debug("Packet is not a BSM, TIM or Map message: {}", hexPacketParsed); - } else { - log.debug("Base packet: {}", hexPacketParsed); - hexPacketParsed = stripTrailingZeros(hexPacketParsed); - log.debug("Stripped packet: {}", hexPacketParsed); - } - return HexUtils.fromHexString(hexPacketParsed); + if (hexPacketParsed.isEmpty()) { + hexPacketParsed = hexString; + log.debug("Packet is not a BSM, TIM or Map message: {}", hexPacketParsed); + } else { + log.debug("Base packet: {}", hexPacketParsed); + hexPacketParsed = stripTrailingZeros(hexPacketParsed); + log.debug("Stripped packet: {}", hexPacketParsed); } - - /* - * Strips the 1609.3 and unsigned 1609.2 headers if they are present. - * Will return the payload with a signed 1609.2 header if it is present. - * Otherwise, returns just the payload. - */ - public static String stripDot3Header(String hexString, String payloadStartFlag) { - int payloadStartIndex = findValidStartFlagLocation(hexString,payloadStartFlag); - String headers = hexString.substring(0, payloadStartIndex); - String payload = hexString.substring(payloadStartIndex); - log.debug("Base payload: {}", payload); - String strippedPayload = stripTrailingZeros(payload); - log.debug("Stripped payload: {}", strippedPayload); - // Look for the index of the start flag of a signed 1609.2 header - int signedDot2StartIndex = headers.indexOf("038100"); - if (signedDot2StartIndex == -1) - return strippedPayload; - else - return headers.substring(signedDot2StartIndex) + strippedPayload; + return HexUtils.fromHexString(hexPacketParsed); + } + + /** + * Strips the 1609.3 and unsigned 1609.2 headers if they are present. Will return the payload with + * a signed 1609.2 header if it is present. Otherwise, returns just the payload. + */ + public static String stripDot3Header(String hexString, String payloadStartFlag) { + int payloadStartIndex = findValidStartFlagLocation(hexString, payloadStartFlag); + String headers = hexString.substring(0, payloadStartIndex); + String payload = hexString.substring(payloadStartIndex); + log.debug("Base payload: {}", payload); + String strippedPayload = stripTrailingZeros(payload); + log.debug("Stripped payload: {}", strippedPayload); + // Look for the index of the start flag of a signed 1609.2 header + int signedDot2StartIndex = headers.indexOf("038100"); + if (signedDot2StartIndex == -1) { + return strippedPayload; + } else { + return headers.substring(signedDot2StartIndex) + strippedPayload; + } + } + + /** + * Determines the message type based off the most likely start flag. + * + * @param payload The OdeMsgPayload to check the content of. + */ + public static String determineMessageType(OdeMsgPayload payload) { + String messageType = ""; + try { + JSONObject payloadJson = JsonUtils.toJSONObject(payload.getData().toJson()); + String hexString = payloadJson.getString("bytes").toLowerCase(); + hexString = stripTrailingZeros(hexString); + messageType = determineHexPacketType(hexString); + + } catch (JsonUtilsException e) { + log.error("JsonUtilsException while checking message header.", e); + } + return messageType; + } + + /** + * Determines the type of hex packet based on predefined start flags for various message types + * defined by {@link SupportedMessageType}. + * + * @param hexString the hexadecimal string representing a packet whose type is to be determined + * @return a string indicating the type of the packet, such as "MAP", "SPAT", "TIM", "BSM", "SSM", + * "PSM", or "SRM". If no valid type is found, returns an empty string. + */ + public static String determineHexPacketType(String hexString) { + HashMap flagIndexes = new HashMap<>(); + + flagIndexes.put("MAP", + findValidStartFlagLocation(hexString, SupportedMessageType.MAP.getStartFlag())); + flagIndexes.put("SPAT", + findValidStartFlagLocation(hexString, SupportedMessageType.SPAT.getStartFlag())); + flagIndexes.put("TIM", + findValidStartFlagLocation(hexString, SupportedMessageType.TIM.getStartFlag())); + flagIndexes.put("BSM", + findValidStartFlagLocation(hexString, SupportedMessageType.BSM.getStartFlag())); + flagIndexes.put("SSM", + findValidStartFlagLocation(hexString, SupportedMessageType.SSM.getStartFlag())); + flagIndexes.put("PSM", + findValidStartFlagLocation(hexString, SupportedMessageType.PSM.getStartFlag())); + flagIndexes.put("SRM", + findValidStartFlagLocation(hexString, SupportedMessageType.SRM.getStartFlag())); + + int lowestIndex = Integer.MAX_VALUE; + String messageType = ""; + for (String key : flagIndexes.keySet()) { + if (flagIndexes.get(key) == -1) { + log.debug("This message is not of type {}", key); + continue; + } + if (flagIndexes.get(key) < lowestIndex) { + messageType = key; + lowestIndex = flagIndexes.get(key); + } + } + return messageType; + } + + /** + * Searches for the location of the given start flag in the provided hex string and ensures it is + * on an even numbered byte. If the start flag is found at the beginning of the string or not + * found at all, it returns immediately. Otherwise, it continues searching from the fifth + * position. The method ensures that the found start flag is located on an even byte boundary. + * + * @param hexString the string representation of the message in hexadecimal format where the + * search for the start flag will be conducted. + * @param startFlag the specific flag pattern to locate within the given hex string, indicating + * the start of a valid message. + * @return the index of the start flag within the hex string if found, and located on an even byte + * boundary; -1 if not found. + */ + public static int findValidStartFlagLocation(String hexString, String startFlag) { + int index = hexString.indexOf(startFlag); + + // If the message has a header, make sure not to misidentify the message by the header + if (index == 0 || index == -1) { + return index; + } else { + index = hexString.indexOf(startFlag, 4); } - /** - * Determines the message type based off the most likely start flag - * - * @param payload The OdeMsgPayload to check the content of. - */ - public static String determineMessageType(OdeMsgPayload payload) { - String messageType = ""; - try { - JSONObject payloadJson = JsonUtils.toJSONObject(payload.getData().toJson()); - String hexString = payloadJson.getString("bytes").toLowerCase(); - hexString = stripTrailingZeros(hexString); - messageType = determineHexPacketType(hexString); - - } catch (JsonUtilsException e) { - log.error("JsonUtilsException while checking message header.", e); - } - return messageType; - } - - public static String determineHexPacketType(String hexString){ - - String messageType = ""; - HashMap flagIndexes = new HashMap<>(); - - flagIndexes.put("MAP", findValidStartFlagLocation(hexString, SupportedMessageType.MAP.getStartFlag())); - flagIndexes.put("SPAT", findValidStartFlagLocation(hexString, SupportedMessageType.SPAT.getStartFlag())); - flagIndexes.put("TIM", findValidStartFlagLocation(hexString, SupportedMessageType.TIM.getStartFlag())); - flagIndexes.put("BSM", findValidStartFlagLocation(hexString, SupportedMessageType.BSM.getStartFlag())); - flagIndexes.put("SSM", findValidStartFlagLocation(hexString, SupportedMessageType.SSM.getStartFlag())); - flagIndexes.put("PSM", findValidStartFlagLocation(hexString, SupportedMessageType.PSM.getStartFlag())); - flagIndexes.put("SRM", findValidStartFlagLocation(hexString, SupportedMessageType.SRM.getStartFlag())); - - int lowestIndex = Integer.MAX_VALUE; - for (String key : flagIndexes.keySet()) { - if (flagIndexes.get(key) == -1) { - log.debug("This message is not of type {}", key); - continue; - } - if (flagIndexes.get(key) < lowestIndex) { - messageType = key; - lowestIndex = flagIndexes.get(key); - } - } - return messageType; + // Make sure start flag is on an even numbered byte + while (index != -1 && index % 2 != 0) { + index = hexString.indexOf(startFlag, index + 1); + } + return index; + } + + + /** + * Trims extra `00` bytes off of the end of an ASN1 payload string. This removes the padded bytes + * added to the payload when receiving ASN1 payloads and leaves one remaining byte of `00`s for + * decoding. + * + * @param payload The OdeMsgPayload as a string to trim. + */ + public static String stripTrailingZeros(String payload) { + // Remove trailing '0's + while (payload.endsWith("0")) { + payload = payload.substring(0, payload.length() - 1); } - public static int findValidStartFlagLocation(String hexString, String startFlag) { - int index = hexString.indexOf(startFlag); - - // If the message has a header, make sure not to misidentify the message by the header - if (index == 0 || index == -1) { - return index; - } else { - index = hexString.indexOf(startFlag, 4); - } - - // Make sure start flag is on an even numbered byte - while (index != -1 && index % 2 != 0) { - index = hexString.indexOf(startFlag, index + 1); - } - return index; + // Ensure the payload length is even + if (payload.length() % 2 != 0) { + payload += "0"; } + // Append '00' to ensure one remaining byte of '00's for decoding + payload += "00"; - /** - * Trims extra `00` bytes off of the end of an ASN1 payload string - * This is remove the padded bytes added to the payload when receiving ASN1 payloads - * and leaves one remaining byte of `00`s for decoding - * - * @param payload The OdeMsgPayload as a string to trim. - */ - public static String stripTrailingZeros(String payload) { - // Remove trailing '0's - while (payload.endsWith("0")) { - payload = payload.substring(0, payload.length() - 1); - } - - // Ensure the payload length is even - if (payload.length() % 2 != 0) { - payload += "0"; - } - - // Append '00' to ensure one remaining byte of '00's for decoding - payload += "00"; - - return payload; - } + return payload; + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java index 6ed4e2c9a..40ed1b4c8 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java @@ -1,5 +1,11 @@ package us.dot.its.jpo.ode.kafka; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static us.dot.its.jpo.ode.test.utilities.ApprovalTestCase.deserializeTestCases; + +import java.io.IOException; +import java.util.List; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; @@ -9,7 +15,8 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.core.DefaultKafkaProducerFactory; @@ -17,63 +24,79 @@ import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; +import us.dot.its.jpo.ode.kafka.listeners.Asn1DecodeMAPJSONListener; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.ApprovalTestCase; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @Slf4j -@SpringBootTest(properties = {"ode.kafka.topics.raw-encoded-json.map=topic.Asn1DecoderTestMAPJSON", - "ode.kafka.topics.asn1.decoder-input=topic.Asn1DecoderMAPInput"}) -@ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) +@SpringBootTest( + classes = { + KafkaProducerConfig.class, + KafkaConsumerConfig.class, + Asn1DecodeMAPJSONListener.class + }, + properties = { + "ode.kafka.topics.raw-encoded-json.map=topic.Asn1DecoderTestMAPJSON", + "ode.kafka.topics.asn1.decoder-input=topic.Asn1DecoderMAPInput" + }) +@EnableConfigurationProperties +@ContextConfiguration(classes = { + UDPReceiverProperties.class, OdeKafkaProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) @DirtiesContext class Asn1DecodeMAPJSONTest { - @Value(value = "${ode.kafka.topics.raw-encoded-json.map}") - private String rawEncodedMapJson; + @Value(value = "${ode.kafka.topics.raw-encoded-json.map}") + private String rawEncodedMapJson; - @Value(value = "${ode.kafka.topics.asn1.decoder-input}") - private String asn1DecoderInput; + @Value(value = "${ode.kafka.topics.asn1.decoder-input}") + private String asn1DecoderInput; - private static final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + private static final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - @Test - void testProcess_ApprovalTest() throws IOException { - Awaitility.setDefaultTimeout(250, java.util.concurrent.TimeUnit.MILLISECONDS); - try { - EmbeddedKafkaHolder.getEmbeddedKafka().addTopics( - new NewTopic(rawEncodedMapJson, 1, (short) 1), - new NewTopic(asn1DecoderInput, 1, (short) 1) - ); - } catch (Exception e) { - log.warn("New topics not created: {}", e.getMessage()); - } + @Test + void testProcess_ApprovalTest() throws IOException { + Awaitility.setDefaultTimeout(250, java.util.concurrent.TimeUnit.MILLISECONDS); + try { + EmbeddedKafkaHolder.getEmbeddedKafka().addTopics( + new NewTopic(rawEncodedMapJson, 1, (short) 1), + new NewTopic(asn1DecoderInput, 1, (short) 1) + ); + } catch (Exception e) { + log.warn("New topics not created: {}", e.getMessage()); + } - String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; - List approvalTestCases = deserializeTestCases(path); + String path = + "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; + List approvalTestCases = deserializeTestCases(path); - Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); - DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); - Producer producer = producerFactory.createProducer(); + Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); + DefaultKafkaProducerFactory producerFactory = + new DefaultKafkaProducerFactory<>(producerProps); + Producer producer = producerFactory.createProducer(); - Map consumerProps = KafkaTestUtils.consumerProps(this.getClass().getSimpleName(), "false", embeddedKafka); - DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); - Consumer testConsumer = cf.createConsumer(); - embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, asn1DecoderInput); + Map consumerProps = + KafkaTestUtils.consumerProps(this.getClass().getSimpleName(), "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer testConsumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, asn1DecoderInput); - for (ApprovalTestCase approvalTestCase : approvalTestCases) { - // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer - ProducerRecord r = new ProducerRecord<>(rawEncodedMapJson, approvalTestCase.getInput()); - var sent = producer.send(r); - Awaitility.await().until(sent::isDone); + for (ApprovalTestCase approvalTestCase : approvalTestCases) { + // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer + ProducerRecord r = + new ProducerRecord<>(rawEncodedMapJson, approvalTestCase.getInput()); + var sent = producer.send(r); + Awaitility.await().until(sent::isDone); - ConsumerRecord actualRecord = KafkaTestUtils.getSingleRecord(testConsumer, asn1DecoderInput); - assertEquals(approvalTestCase.getExpected(), actualRecord.value(), approvalTestCase.getDescription()); - } + ConsumerRecord actualRecord = + KafkaTestUtils.getSingleRecord(testConsumer, asn1DecoderInput); + assertEquals(approvalTestCase.getExpected(), actualRecord.value(), + approvalTestCase.getDescription()); } + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/ConfluentPropertiesTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/ConfluentPropertiesTest.java new file mode 100644 index 000000000..d791408f3 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/ConfluentPropertiesTest.java @@ -0,0 +1,27 @@ +package us.dot.its.jpo.ode.kafka; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class ConfluentPropertiesTest { + + @Test + void buildConfluentProperties() { + ConfluentProperties confluentProperties = new ConfluentProperties(); + confluentProperties.setPassword("password123"); + confluentProperties.setUsername("username322"); + + Map expected = new HashMap<>(); + expected.put("ssl.endpoint.identification.algorithm", "https"); + expected.put("security.protocol", "SASL_SSL"); + expected.put("sasl.mechanism", "PLAIN"); + expected.put("sasl.jaas.config", + "org.apache.kafka.common.security.plain.PlainLoginModule " + + "required username=\"username322\" password=\"password123\";"); + + assertEquals(expected, confluentProperties.buildConfluentProperties()); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java new file mode 100644 index 000000000..5b44d0851 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java @@ -0,0 +1,123 @@ +package us.dot.its.jpo.ode.kafka; + +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; +import org.awaitility.Awaitility; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.model.OdeObject; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; + +@Slf4j +@SpringBootTest( + classes = { + KafkaProducerConfig.class, + OdeKafkaProperties.class, + KafkaProperties.class + } +) +@EnableConfigurationProperties +class KafkaProducerConfigTest { + + @Autowired + KafkaProducerConfig kafkaProducerConfig; + @Autowired + OdeKafkaProperties odeKafkaProperties; + + EmbeddedKafkaBroker embeddedKafka; + KafkaTemplate stringKafkaTemplate; + KafkaTemplate odeObjectKafkaTemplate; + + @BeforeEach + public void beforeClass() { + embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + var topics = embeddedKafka.getTopics(); + for (String topic : odeKafkaProperties.getDisabledTopics()) { + if (!topics.contains(topic)) { + embeddedKafka.addTopics(new NewTopic(topic, 1, (short) 1)); + } + } + stringKafkaTemplate = + kafkaProducerConfig.kafkaTemplate(kafkaProducerConfig.producerFactory()); + odeObjectKafkaTemplate = + kafkaProducerConfig.odeDataKafkaTemplate(kafkaProducerConfig.odeDataProducerFactory()); + } + + @Test + void odeDataProducerFactory_shouldReturnNonNull() { + ProducerFactory producerFactory = + kafkaProducerConfig.odeDataProducerFactory(); + assertNotNull(producerFactory); + } + + @Test + void odeDataProducerFactory_shouldReturnDefaultKafkaProducerFactory() { + ProducerFactory producerFactory = + kafkaProducerConfig.odeDataProducerFactory(); + assertNotNull(producerFactory); + assertInstanceOf(DefaultKafkaProducerFactory.class, producerFactory); + } + + @Test + void kafkaTemplateInterceptorPreventsSendingToDisabledTopics() { + var consumerProps = + KafkaTestUtils.consumerProps("interceptor-disabled", + "false", + embeddedKafka); + var cf = new DefaultKafkaConsumerFactory(consumerProps); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromAllEmbeddedTopics(consumer); + + // Attempting to send to a disabled topic + for (String topic : odeKafkaProperties.getDisabledTopics()) { + assertThrows(DisabledTopicException.class, + () -> stringKafkaTemplate.send(topic, "key", "value")); + + var records = KafkaTestUtils.getEndOffsets(consumer, topic, 0); + // Assert that the message we attempted to send to the disabled topic was intercepted + // and not sent + assertTrue(records + .entrySet() + .stream() + .allMatch(e -> e.getValue() == 0L) + ); + } + } + + @Test + void kafkaTemplateInterceptorAllowsSendingToTopicsNotInDisabledSet() { + String enabledTopic = "topic.enabled" + this.getClass().getSimpleName(); + embeddedKafka.addTopics(new NewTopic(enabledTopic, 1, (short) 1)); + + var consumerProps = + KafkaTestUtils.consumerProps("interceptor-enabled", "false", embeddedKafka); + var cf = new DefaultKafkaConsumerFactory(consumerProps); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, enabledTopic); + + // Attempting to send to a topic not in the disabledTopics set with the string template + var stringCompletableFuture = stringKafkaTemplate.send(enabledTopic, "key", "value"); + Awaitility.await().until(stringCompletableFuture::isDone); + + var records = KafkaTestUtils.getEndOffsets(consumer, enabledTopic, 0); + assertTrue(records.entrySet().stream().allMatch(e -> e.getValue() > 0L)); + } + +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java index c51539e82..61b83e81f 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java @@ -1,6 +1,11 @@ package us.dot.its.jpo.ode.services.asn1; +import static org.junit.jupiter.api.Assertions.assertEquals; + import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.util.List; +import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; @@ -9,92 +14,115 @@ import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import us.dot.its.jpo.ode.kafka.KafkaConsumerConfig; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.listeners.Asn1DecodedDataListener; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeMapData; -import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import java.io.IOException; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.ApprovalTestCase; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; @Slf4j -@SpringBootTest(properties = { +@SpringBootTest( + classes = { + Asn1DecodedDataListener.class, + KafkaProperties.class, + KafkaProducerConfig.class, + KafkaConsumerConfig.class}, + properties = { "ode.kafka.topics.asn1.decoder-output=topic.Asn1DecoderOutputRouterApprovalTest", "ode.kafka.topics.pojo.tx-map=topic.OdeMapTxPojoRouterApprovalTest", "ode.kafka.topics.json.map=topic.OdeMapJsonRouterApprovalTest" + }) +@EnableConfigurationProperties +@ContextConfiguration(classes = { + UDPReceiverProperties.class, OdeKafkaProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class }) @DirtiesContext class Asn1DecodedDataRouterApprovalTest { - @Value("${ode.kafka.topics.asn1.decoder-output}") - private String decoderOutputTopic; - - @Value("${ode.kafka.topics.pojo.tx-map}") - private String txMapTopic; - - @Value("${ode.kafka.topics.json.map}") - private String jsonMapTopic; - - EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - - @Test - void testAsn1DecodedDataRouter() throws IOException { - NewTopic inputTopic = new NewTopic(decoderOutputTopic, 1, (short) 1); - NewTopic outputTopicTx = new NewTopic(txMapTopic, 1, (short) 1); - NewTopic outputTopicJson = new NewTopic(jsonMapTopic, 1, (short) 1); - try { - embeddedKafka.addTopics(inputTopic, outputTopicTx, outputTopicJson); - } catch (RuntimeException e) { - // this usually happens when the topic already exists on the broker. We don't care if it already exists and - // add topic fails. we only care that the topics are created and we can run the tests. - log.warn("Exception while adding input topic", e); - } - - List testCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); - - Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); - DefaultKafkaProducerFactory producerFactory = new DefaultKafkaProducerFactory<>(producerProps); - Producer producer = producerFactory.createProducer(); - - Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); - DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); - - Consumer consumer = cf.createConsumer(); - embeddedKafka.consumeFromEmbeddedTopics(consumer, txMapTopic, jsonMapTopic); - - for (ApprovalTestCase testCase : testCases) { - ProducerRecord producerRecord = new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); - var sent = producer.send(producerRecord); - Awaitility.await().until(sent::isDone); - - String received = KafkaTestUtils.getSingleRecord(consumer, txMapTopic).value(); - ObjectMapper mapper = new ObjectMapper(); - OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); - OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); - assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), "Failed test case: " + testCase.getDescription()); - // discard the JSON output - KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic); - } - - List jsonTestCases = ApprovalTestCase.deserializeTestCases("src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json"); - - for (ApprovalTestCase testCase : jsonTestCases) { - ProducerRecord producerRecord = new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); - producer.send(producerRecord); - - String received = KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic).value(); - ObjectMapper mapper = new ObjectMapper(); - OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); - OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); - assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), "Failed test case: " + testCase.getDescription()); - } + @Value("${ode.kafka.topics.asn1.decoder-output}") + private String decoderOutputTopic; + + @Value("${ode.kafka.topics.pojo.tx-map}") + private String txMapTopic; + + @Value("${ode.kafka.topics.json.map}") + private String jsonMapTopic; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testAsn1DecodedDataRouter() throws IOException { + NewTopic inputTopic = new NewTopic(decoderOutputTopic, 1, (short) 1); + NewTopic outputTopicTx = new NewTopic(txMapTopic, 1, (short) 1); + NewTopic outputTopicJson = new NewTopic(jsonMapTopic, 1, (short) 1); + try { + embeddedKafka.addTopics(inputTopic, outputTopicTx, outputTopicJson); + } catch (Exception e) { + // Ignore. We only care that the topics exist not that we created them here + } + + @SuppressWarnings("checkstyle:linelength") + List testCases = ApprovalTestCase.deserializeTestCases( + "src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); + + Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); + DefaultKafkaProducerFactory producerFactory = + new DefaultKafkaProducerFactory<>(producerProps); + Producer producer = producerFactory.createProducer(); + + Map consumerProps = + KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(consumer, txMapTopic, jsonMapTopic); + + for (ApprovalTestCase testCase : testCases) { + ProducerRecord producerRecord = + new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); + var sent = producer.send(producerRecord); + Awaitility.await().until(sent::isDone); + + String received = KafkaTestUtils.getSingleRecord(consumer, txMapTopic).value(); + ObjectMapper mapper = new ObjectMapper(); + OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); + OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); + assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), + "Failed test case: " + testCase.getDescription()); + // discard the JSON output + KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic); + } + + @SuppressWarnings("checkstyle:linelength") + List jsonTestCases = ApprovalTestCase.deserializeTestCases( + "src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json"); + + for (ApprovalTestCase testCase : jsonTestCases) { + ProducerRecord producerRecord = + new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); + producer.send(producerRecord); + + String received = KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic).value(); + ObjectMapper mapper = new ObjectMapper(); + OdeMapData receivedMapData = mapper.readValue(received, OdeMapData.class); + OdeMapData expectedMapData = mapper.readValue(testCase.getExpected(), OdeMapData.class); + assertEquals(expectedMapData.toJson(), receivedMapData.toJson(), + "Failed test case: " + testCase.getDescription()); } + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java index 485e96d67..4f3d07ff8 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeBSMJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -15,48 +17,48 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeBsmMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings({"checkstyle:abbreviationAsWordInName", "checkstyle:linelength"}) @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeBSMJSONTest { - private final String json = "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - - Asn1DecodeBSMJSON testDecodeBsmJson = new Asn1DecodeBSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); - - // Validate the metadata - OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeBsmMetadata.BsmSource.EV, jsonMetadataObj.getBsmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics( + new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. } + + Asn1DecodeBSMJSON testDecodeBsmJson = + new Asn1DecodeBSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + String json = + "{\"metadata\":{\"bsmSource\":\"EV\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"be071349-9bb6-4b66-b1c7-8df1f9e0cb74\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T16:46:45.297174600Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"03810040038081B1001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodeBsmJson.process(json); + + // Validate the metadata + OdeBsmMetadata jsonMetadataObj = (OdeBsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeBsmMetadata.BsmSource.EV, jsonMetadataObj.getBsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + String expectedPayload = + "{\"bytes\":\"001480AD4644A9EA5442BC26E97C7496576E052569B214000070007050FD7D0FA1007FFF8000681250020214C1C0FF64BFFA0FB84F720FF71BFF9500DFFFC0FF564006D001FFFC0FF5BBFE5B031FFFC0FF573FF73075FFFC0FF973FFB708FFFFC0FFEFC00B50B5FFFC0FFF0401150BBFFFC0FFDF4015D0C1FFFC0FFB9C01690C7FFFC0FFC0401550C9FFFC0FFBAC014F0C9FFFC0FFBBC01530CBFFFC0FFBB400B30E7FFFC100383FFCD0E3FFFCFFFEC800400120000243450D45B978805B073A8672E91E9D80824A65C65F85E35B61502149263F000FE804E6B84AF66507D51690DE76F30D1468A68F8986B58E6AECB2C5FC4766C223F0B977E87678DDF714FE123C483622CC7500\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java index 6d310bb62..a6c4d5ab7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodePSMJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -15,47 +17,49 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdePsmMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings("checkstyle:abbreviationAsWordInName") @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodePSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - Asn1DecodePSMJSON testDecodePsmJson = new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); - - // Validate the metadata - OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); - assertEquals(OdePsmMetadata.PsmSource.RSU, jsonMetadataObj.getPsmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. } + Asn1DecodePSMJSON testDecodePsmJson = + new Asn1DecodePSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + @SuppressWarnings("checkstyle:linelength") + String json = + "{\"metadata\":{\"recordType\":\"psmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"fa3dfe1b-80cd-45cb-ae2c-c604a214fe56\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:16:35.212860500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"UNKNOWN\",\"sanitized\":false,\"psmSource\":\"RSU\",\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC798601000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodePsmJson.process(json); + + // Validate the metadata + OdePsmMetadata jsonMetadataObj = (OdePsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdePsmMetadata.PsmSource.RSU, jsonMetadataObj.getPsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + // Validate the payload + @SuppressWarnings("checkstyle:linelength") + String expectedPayload = + "{\"bytes\":\"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java index a2530c228..758e1a7f7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSPATJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -15,48 +17,48 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSpatMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings({"checkstyle:abbreviationAsWordInName", "checkstyle:linelength"}) @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSPATJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - - Asn1DecodeSPATJSON testDecodeSpatJson = new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput() ); - - OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); - - // Validate the metadata - OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeSpatMetadata.SpatSource.RSU, jsonMetadataObj.getSpatSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. } + + Asn1DecodeSPATJSON testDecodeSpatJson = + new Asn1DecodeSPATJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + String json = + "{\"metadata\":{\"recordType\":\"spatTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"5ec410a3-bec6-4724-9601-1e08778e1dfc\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:43:22.604870100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"spatSource\":\"RSU\",\"originIp\":\"192.168.0.1\",\"isCertPresent\":false},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodeSpatJson.process(json); + + // Validate the metadata + OdeSpatMetadata jsonMetadataObj = (OdeSpatMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSpatMetadata.SpatSource.RSU, jsonMetadataObj.getSpatSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + // Validate the payload + String expectedPayload = + "{\"bytes\":\"00134700081132000000E437070010434257925790010232119A11CE800C10D095E495E400808684AF24AF20050434257925790030232119A11CE801C10D095E495E401008684AF24AF200\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java index e50f73d8b..dbe15fdc0 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSRMJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -15,48 +17,50 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSrmMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings({"checkstyle:abbreviationAsWordInName", "checkstyle:linelength"}) @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSRMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - - Asn1DecodeSRMJSON testDecodeSrmJson = new Asn1DecodeSRMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); - - // Validate the metadata - OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeSrmMetadata.SrmSource.RSU, jsonMetadataObj.getSrmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic } + + Asn1DecodeSRMJSON testDecodeSrmJson = + new Asn1DecodeSRMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + String json = + "{\"metadata\":{\"recordType\":\"srmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"190cbd65-d1e2-488a-ba42-b7d3f03a5c69\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:24:04.113614500Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"srmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodeSrmJson.process(json); + + // Validate the metadata + OdeSrmMetadata jsonMetadataObj = (OdeSrmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSrmMetadata.SrmSource.RSU, jsonMetadataObj.getSrmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + // Validate the payload + String expectedPayload = + "{\"bytes\":\"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java index d0609c35b..66e1b878c 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeSSMJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -15,48 +17,49 @@ import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeSsmMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings({"checkstyle:abbreviationAsWordInName", "checkstyle:linelength"}) @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeSSMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - - Asn1DecodeSSMJSON testDecodeSsmJson = new Asn1DecodeSSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); - - // Validate the metadata - OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeSsmMetadata.SsmSource.RSU, jsonMetadataObj.getSsmSource()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic } + + Asn1DecodeSSMJSON testDecodeSsmJson = + new Asn1DecodeSSMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + String json = + "{\"metadata\":{\"recordType\":\"ssmTx\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"c4e4e92d-dccc-45f5-813f-7d36795529a0\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:31:02.907835400Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\",\"ssmSource\":\"RSU\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001E120000000005E9C04071A26614C06000040BA000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodeSsmJson.process(json); + + // Validate the metadata + OdeSsmMetadata jsonMetadataObj = (OdeSsmMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeSsmMetadata.SsmSource.RSU, jsonMetadataObj.getSsmSource()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + // Validate the payload + String expectedPayload = "{\"bytes\":\"001E120000000005E9C04071A26614C06000040BA000\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java index c1380f751..ab8c949c5 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/message/Asn1DecodeTIMJSONTest.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.services.asn1.message; +import static org.junit.jupiter.api.Assertions.assertEquals; + import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONException; import org.junit.jupiter.api.Test; @@ -16,48 +18,50 @@ import us.dot.its.jpo.ode.model.OdeAsn1Payload; import us.dot.its.jpo.ode.model.OdeMsgMetadata; import us.dot.its.jpo.ode.model.OdeTimMetadata; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; - -import static org.junit.jupiter.api.Assertions.assertEquals; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +@SuppressWarnings({"checkstyle:abbreviationAsWordInName", "checkstyle:linelength"}) @ExtendWith(SpringExtension.class) @ContextConfiguration(initializers = ConfigDataApplicationContextInitializer.class) @EnableConfigurationProperties(value = {OdeKafkaProperties.class, Asn1CoderTopics.class}) class Asn1DecodeTIMJSONTest { - private final String json = "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; - - @Autowired - OdeKafkaProperties odeKafkaProperties; - - @Autowired - Asn1CoderTopics asn1CoderTopics; - - @Test - void testProcess() throws JSONException { - var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - try { - embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topic exists not that it was created in this test. - // this test doesn't actually consume anything from the queue, it just needs the kafka broker running - // and configured with the decoder input topic so that it can verify the message produced to the topic - } - - Asn1DecodeTIMJSON testDecodeTimJson = new Asn1DecodeTIMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); - - OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); - - // Validate the metadata - OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); - assertEquals(OdeMsgMetadata.GeneratedBy.RSU, jsonMetadataObj.getRecordGeneratedBy()); - assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); - assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); - assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); - - // Validate the payload - String expectedPayload = "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; - OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); - assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); - assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + + @Autowired + OdeKafkaProperties odeKafkaProperties; + + @Autowired + Asn1CoderTopics asn1CoderTopics; + + @Test + void testProcess() throws JSONException { + var embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + try { + embeddedKafka.addTopics(new NewTopic(asn1CoderTopics.getDecoderInput(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topic exists not that it was created in this test. + // this test doesn't actually consume anything from the queue, it just needs the kafka broker running + // and configured with the decoder input topic so that it can verify the message produced to the topic } + + Asn1DecodeTIMJSON testDecodeTimJson = + new Asn1DecodeTIMJSON(odeKafkaProperties, asn1CoderTopics.getDecoderInput()); + + String json = + "{\"metadata\":{\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"payloadType\":\"us.dot.its.jpo.ode.model.OdeAsn1Payload\",\"serialId\":{\"streamId\":\"9952caf6-81bd-490d-ad95-47dee31c3ba8\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2024-03-15T19:38:48.578500100Z\",\"schemaVersion\":6,\"maxDurationTime\":0,\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"originIp\":\"192.168.0.1\"},\"payload\":{\"dataType\":\"us.dot.its.jpo.ode.model.OdeHexByteArray\",\"data\":{\"bytes\":\"0381004003807C001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"}}}"; + OdeAsn1Data resultOdeObj = testDecodeTimJson.process(json); + + // Validate the metadata + OdeTimMetadata jsonMetadataObj = (OdeTimMetadata) resultOdeObj.getMetadata(); + assertEquals(OdeMsgMetadata.GeneratedBy.RSU, jsonMetadataObj.getRecordGeneratedBy()); + assertEquals("unsecuredData", jsonMetadataObj.getEncodings().getFirst().getElementName()); + assertEquals("MessageFrame", jsonMetadataObj.getEncodings().getFirst().getElementType()); + assertEquals(EncodingRule.UPER, jsonMetadataObj.getEncodings().getFirst().getEncodingRule()); + + // Validate the payload + String expectedPayload = + "{\"bytes\":\"001F79201000000000012AA366D080729B8987D859717EE22001FFFE4FD0011589D828007E537130FB0B2E2FDC440001F46FFFF002B8B2E46E926E27CE6813D862CB90EDC9B89E11CE2CB8E98F9B89BCC4050518B2E365B66E26AE3B8B2E291A66E2591D8141462CB873969B89396C62CB86AFE9B89208E00000131560018300023E43A6A1351800023E4700EFC51881010100030180C620FB90CAAD3B9C5082080E1DDC905E10168E396921000325A0D73B83279C83010180034801090001260001808001838005008001F0408001828005008001304000041020407E800320409780050080012040000320409900018780032040958005000001E0408183E7139D7B70987019B526B8A950052F5C011D3C4B992143E885C71F95DA6071658082346CC03A50D66801F65288C30AB39673D0494536C559047E457AD291C99C20A7FB1244363E993EE3EE98C78742609340541DA01545A0F7339C26A527903576D300\"}"; + OdeAsn1Payload jsonPayloadObj = (OdeAsn1Payload) resultOdeObj.getPayload(); + assertEquals("us.dot.its.jpo.ode.model.OdeHexByteArray", jsonPayloadObj.getDataType()); + assertEquals(expectedPayload, jsonPayloadObj.getData().toString()); + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/ApprovalTestCase.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/ApprovalTestCase.java new file mode 100644 index 000000000..a743115a9 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/ApprovalTestCase.java @@ -0,0 +1,58 @@ +package us.dot.its.jpo.ode.test.utilities; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import lombok.Getter; +import lombok.Setter; +import org.json.JSONArray; +import org.json.JSONObject; + +/** + * Represents a test case for an approval test, containing a description, input, and expected + * output. + */ +@Getter +@Setter +public class ApprovalTestCase { + + public String description; + public String input; + public String expected; + + /** + * Deserializes a list of approval test cases from a JSON file located at the specified path. The + * JSON file is expected to have a structure where the test cases are contained in an array named + * "cases". Each test case is represented by a JSON object that includes a "description", "input", + * and "expected" field. + * + * @param path the file path to the JSON file containing the test cases + * @return a list of ApprovalTestCase objects deserialized from the JSON file + * @throws IOException if an I/O error occurs while reading the file + */ + public static List deserializeTestCases(String path) throws IOException { + List cases = new ArrayList<>(); + File file = new File(path); + byte[] jsonData = Files.readAllBytes(file.toPath()); + JSONObject jsonObject = new JSONObject(new String(jsonData)); + + JSONArray jsonArray = jsonObject.getJSONArray("cases"); + + for (int i = 0; i < jsonArray.length(); i++) { + ApprovalTestCase approvalTestCase = new ApprovalTestCase(); + JSONObject json = jsonArray.getJSONObject(i); + + approvalTestCase.setDescription(json.getString("description")); + + Object input = json.get("input"); + approvalTestCase.setInput(input.toString()); + + approvalTestCase.setExpected(json.get("expected").toString()); + + cases.add(approvalTestCase); + } + return cases; + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java new file mode 100644 index 000000000..f87d5ddbb --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java @@ -0,0 +1,54 @@ +package us.dot.its.jpo.ode.test.utilities; + +import org.springframework.kafka.KafkaException; +import org.springframework.kafka.test.EmbeddedKafkaBroker; + +/** + * The EmbeddedKafkaHolder class is a utility for managing a singleton instance of an embedded Kafka + * broker for testing purposes. It ensures that the embedded Kafka broker is started only once + * throughout the application lifecycle. + * + *

This class initializes an embedded Kafka broker with a specified configuration, which + * includes + * a single broker and auto-start enabled. The broker list property is set to + * "spring.kafka.bootstrap-servers". + * + *

The embedded Kafka instance is lazily started when the getEmbeddedKafka method is called + * for the first time. If the broker fails to start, a KafkaException is thrown. + * + *

The class is designed to be non-instantiable with a private constructor. + */ +public final class EmbeddedKafkaHolder { + + private static final EmbeddedKafkaBroker embeddedKafka = new EmbeddedKafkaBroker(1, + true, + 1) + .brokerListProperty("spring.kafka.bootstrap-servers"); + + private static boolean started; + + /** + * Provides access to a singleton instance of an embedded Kafka broker for testing purposes. + * Lazily initializes and starts the broker on the first call with a predefined configuration. If + * the broker fails to start, a KafkaException is thrown. + * + * @return the singleton instance of the embedded Kafka broker + * @throws KafkaException if the embedded broker fails to start + */ + public static EmbeddedKafkaBroker getEmbeddedKafka() { + if (!started) { + try { + embeddedKafka.kafkaPorts(4242); + embeddedKafka.afterPropertiesSet(); + } catch (Exception e) { + throw new KafkaException("Embedded broker failed to start", e); + } + started = true; + } + return embeddedKafka; + } + + private EmbeddedKafkaHolder() { + super(); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/TestUDPClient.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/TestUDPClient.java new file mode 100644 index 000000000..316aa4aad --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/TestUDPClient.java @@ -0,0 +1,51 @@ +package us.dot.its.jpo.ode.test.utilities; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.net.UnknownHostException; +import lombok.extern.slf4j.Slf4j; +import org.apache.tomcat.util.buf.HexUtils; + +/** + * TestUDPClient is a utility class used for sending UDP packets to a specified port. It + * encapsulates the creation of a DatagramSocket and the logic to send data packets to a local + * server. + */ +@Slf4j +public class TestUDPClient { + + private final DatagramSocket socket; + private final InetAddress address; + private final int sendPort; + + /** + * Constructs a new TestUDPClient instance configured to send UDP packets to the specified port on + * the localhost. + * + * @param port the port number on the localhost to which UDP packets will be sent + * @throws SocketException if there is an error creating the DatagramSocket + * @throws UnknownHostException if the local host cannot be resolved + */ + public TestUDPClient(int port) throws SocketException, UnknownHostException { + socket = new DatagramSocket(); + address = InetAddress.getByName("localhost"); + sendPort = port; + } + + /** + * Sends a UDP packet containing the specified message to the configured port on the localhost. + * The message is converted from a hexadecimal string to a byte array before being sent. + * + * @param msg the message to be sent, represented as a hexadecimal string + * @throws IOException if an I/O error occurs during the sending process + */ + public void send(String msg) throws IOException { + byte[] buf = HexUtils.fromHexString(msg); + + DatagramPacket packet = new DatagramPacket(buf, buf.length, address, sendPort); + socket.send(packet); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java deleted file mode 100644 index 7d28b64ba..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/ApprovalTestCase.java +++ /dev/null @@ -1,49 +0,0 @@ -package us.dot.its.jpo.ode.testUtilities; - -import lombok.Getter; -import lombok.Setter; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.List; - -@Getter -@Setter -public class ApprovalTestCase { - - public String description; - public String input; - public String expected; - - public static List deserializeTestCases(String path) throws IOException { - return deserializeTestCases(path, ""); - } - - public static List deserializeTestCases(String path, String startFlag) throws IOException { - List cases = new ArrayList<>(); - File file = new File(path); - byte[] jsonData = Files.readAllBytes(file.toPath()); - JSONObject jsonObject = new JSONObject(new String(jsonData)); - - JSONArray jsonArray = jsonObject.getJSONArray("cases"); - - for (int i = 0; i < jsonArray.length(); i++) { - ApprovalTestCase approvalTestCase = new ApprovalTestCase(); - JSONObject json = jsonArray.getJSONObject(i); - - approvalTestCase.setDescription(json.getString("description")); - - Object input = json.get("input"); - approvalTestCase.setInput(startFlag + input.toString()); // Add the 2-byte length prefix to the input - - approvalTestCase.setExpected(json.get("expected").toString()); - - cases.add(approvalTestCase); - } - return cases; - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java deleted file mode 100644 index e7b4330aa..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/EmbeddedKafkaHolder.java +++ /dev/null @@ -1,30 +0,0 @@ -package us.dot.its.jpo.ode.testUtilities; - -import org.springframework.kafka.KafkaException; -import org.springframework.kafka.test.EmbeddedKafkaBroker; - -public final class EmbeddedKafkaHolder { - - private static final EmbeddedKafkaBroker embeddedKafka = new EmbeddedKafkaBroker(1, true, 1) - .brokerListProperty("spring.kafka.bootstrap-servers"); - - private static boolean started; - - public static EmbeddedKafkaBroker getEmbeddedKafka() { - if (!started) { - try { - embeddedKafka.kafkaPorts(4242); - embeddedKafka.afterPropertiesSet(); - } - catch (Exception e) { - throw new KafkaException("Embedded broker failed to start", e); - } - started = true; - } - return embeddedKafka; - } - - private EmbeddedKafkaHolder() { - super(); - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java deleted file mode 100644 index da50ee6b1..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/testUtilities/TestUDPClient.java +++ /dev/null @@ -1,36 +0,0 @@ -package us.dot.its.jpo.ode.testUtilities; - -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.SocketException; -import java.net.UnknownHostException; - -@Slf4j -public class TestUDPClient { - private DatagramSocket socket; - private InetAddress address; - private int sendPort; - - private byte[] buf; - - public TestUDPClient(int port) throws SocketException, UnknownHostException { - socket = new DatagramSocket(); - address = InetAddress.getByName("localhost"); - sendPort = port; - } - - public void send(String msg) throws IOException { - buf = msg.getBytes(); - DatagramPacket packet = new DatagramPacket(buf, buf.length, address, sendPort); - socket.send(packet); - } - - public void close() { - - socket.close(); - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java new file mode 100644 index 000000000..50fb5583f --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java @@ -0,0 +1,112 @@ +package us.dot.its.jpo.ode.udp.bsm; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.Consumer; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.bsm.receiver-port=15352", + "ode.kafka.topics.raw-encoded-json.bsm=topic.BsmReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class BsmReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + // create the needed topic for production + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getBsm(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topics exist not that they're unique + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + // create the BsmReceiver and submit it to a runner + BsmReceiver bsmReceiver = new BsmReceiver(udpReceiverProperties.getBsm(), kafkaTemplate, + rawEncodedJsonTopics.getBsm()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(bsmReceiver); + + String fileContent = + Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt")); + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getBsm().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "BsmReceiverTest", "true", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getBsm()); + + // read record from produce topic + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getBsm()); + // confirm the stream-id is different, then remove it from both so that we can test equality of all other fields + assertNotEquals(expected, singleRecord.value()); + JSONObject producedJson = new JSONObject(singleRecord.value()); + JSONObject expectedJson = new JSONObject(expected); + + // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals( + expectedJson.toString(2), + producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java new file mode 100644 index 000000000..684cedc3a --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java @@ -0,0 +1,194 @@ +package us.dot.its.jpo.ode.udp.generic; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneOffset; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.generic.receiver-port=15460", + "ode.kafka.topics.raw-encoded-json.bsm=topic.GenericReceiverTestBSM", + "ode.kafka.topics.raw-encoded-json.map=topic.GenericReceiverTestMAP", + "ode.kafka.topics.raw-encoded-json.psm=topic.GenericReceiverTestPSM", + "ode.kafka.topics.raw-encoded-json.spat=topic.GenericReceiverTestSPAT", + "ode.kafka.topics.raw-encoded-json.ssm=topic.GenericReceiverTestSSM", + "ode.kafka.topics.raw-encoded-json.tim=topic.GenericReceiverTestTIM", + "ode.kafka.topics.raw-encoded-json.srm=topic.GenericReceiverTestSRM" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, OdeKafkaProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class GenericReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + try { + embeddedKafka.addTopics( + new NewTopic(rawEncodedJsonTopics.getBsm(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getMap(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getPsm(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getSpat(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getSsm(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getTim(), 1, (short) 1), + new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1) + ); + } catch (Exception e) { + // Ignore topic creation exceptions + } + + GenericReceiver genericReceiver = new GenericReceiver( + udpReceiverProperties.getGeneric(), + kafkaTemplate, rawEncodedJsonTopics + ); + + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(genericReceiver); + + TestUDPClient udpClient = new TestUDPClient( + udpReceiverProperties.getGeneric().getReceiverPort()); + + var consumerProps = KafkaTestUtils.consumerProps("GenericReceiverTest", "true", embeddedKafka); + var cf = new DefaultKafkaConsumerFactory(consumerProps); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(consumer, + rawEncodedJsonTopics.getMap(), + rawEncodedJsonTopics.getSsm(), + rawEncodedJsonTopics.getPsm(), + rawEncodedJsonTopics.getSpat(), + rawEncodedJsonTopics.getTim(), + rawEncodedJsonTopics.getBsm(), + rawEncodedJsonTopics.getSrm() + ); + + DateTimeUtils.setClock(Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneOffset.UTC)); + + // Test the PSM path + String psmFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt")); + String expectedPsm = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json")); + + udpClient.send(psmFileContent); + var psmRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getPsm()); + assertExpected("Produced PSM message does not match expected", psmRecord.value(), expectedPsm); + + // Test the BSM path + String bsmFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt")); + String expectedBsm = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json")); + udpClient.send(bsmFileContent); + + var bsmRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getBsm()); + assertExpected("Produced BSM message does not match expected", bsmRecord.value(), expectedBsm); + + // Test the MAP path + String mapFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP.txt")); + String expectedMap = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP_expected.json")); + udpClient.send(mapFileContent); + + var mapRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getMap()); + assertExpected("Produced MAP message does not match expected", mapRecord.value(), expectedMap); + + // Test the SPAT path + String spatFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt")); + String expectedSpat = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json")); + udpClient.send(spatFileContent); + + var spatRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSpat()); + assertExpected("Produced SPAT message does not match expected", spatRecord.value(), + expectedSpat); + + // Test the SSM path + String ssmFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt")); + String expectedSsm = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json")); + udpClient.send(ssmFileContent); + + var ssmRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSsm()); + assertExpected("Produced SSM message does not match expected", ssmRecord.value(), expectedSsm); + + // Test the TIM path + String timFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt")); + String expectedTim = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json")); + udpClient.send(timFileContent); + + var timRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getTim()); + assertExpected("Produced TIM message does not match expected", timRecord.value(), expectedTim); + + String srmFileContent = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt") + ); + String expectedSrm = Files.readString( + Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json") + ); + udpClient.send(srmFileContent); + + var srmRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSrm()); + assertExpected("Produced SRM message does not match expected", srmRecord.value(), expectedSrm); + } + + private static void assertExpected(String failureMsg, String actual, String expected) { + JSONObject producedJson = new JSONObject(actual); + JSONObject expectedJson = new JSONObject(expected); + + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals(expectedJson.toString(2), producedJson.toString(2), failureMsg); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java index 3c14a6a60..d5fedb099 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java @@ -1,5 +1,16 @@ package us.dot.its.jpo.ode.udp.map; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static us.dot.its.jpo.ode.test.utilities.ApprovalTestCase.deserializeTestCases; + +import java.io.IOException; +import java.time.Clock; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; @@ -7,90 +18,107 @@ import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeMsgMetadata; -import us.dot.its.jpo.ode.testUtilities.ApprovalTestCase; -import us.dot.its.jpo.ode.testUtilities.EmbeddedKafkaHolder; -import us.dot.its.jpo.ode.testUtilities.TestUDPClient; +import us.dot.its.jpo.ode.test.utilities.ApprovalTestCase; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -import java.io.IOException; -import java.time.Clock; -import java.time.Instant; -import java.util.List; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static us.dot.its.jpo.ode.testUtilities.ApprovalTestCase.deserializeTestCases; - @Slf4j -@SpringBootTest(properties = {"ode.kafka.topics.raw-encoded-json.map=topic.MapReceiverTestMAPJSON", "ode.receivers.map.receiver-port=12412"}) +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = {"ode.kafka.topics.raw-encoded-json.map=topic.MapReceiverTestMAPJSON", + "ode.receivers.map.receiver-port=12412"} +) +@EnableConfigurationProperties +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) @DirtiesContext class MapReceiverTest { - private final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - - @Autowired - UDPReceiverProperties udpReceiverProperties; - - @Value(value = "${ode.kafka.topics.raw-encoded-json.map}") - private String rawJsonMapTopic; - - @Value(value = "${ode.receivers.map.receiver-port}") - private int mapReceiverPort; - - @Test - void testMapReceiver() throws IOException { - String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json"; - List approvalTestCases = deserializeTestCases(path, "\u0000\u0012"); - - // Set the clock to a fixed time so that the MapReceiver will produce the same output every time - DateTimeUtils.setClock(Clock.fixed(Instant.parse("2020-01-01T00:00:00Z"), Clock.systemUTC().getZone())); - // Set the static schema version to 7 so that the MapReceiver will produce the same output every time - // This is necessary because the schema version is set in only one of the OdeMsgMetadata constructors (this should be fixed) - // and the schema version is set to the static schema version in the constructor. This means that the schema version - // will be set to 6 for all OdeMsgMetadata objects created in the MapReceiver run method's code path. - OdeMsgMetadata.setStaticSchemaVersion(7); - - try { - embeddedKafka.addTopics(new NewTopic(rawJsonMapTopic, 1, (short) 1)); - } catch (Exception e) { - log.warn("Couldn't create topics. If the error indicates the topics already exist, this message is safe to ignore: {}", e.getMessage()); - } - - // Set up a Kafka consumer - Map consumerProps = KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka); - DefaultKafkaConsumerFactory cf = new DefaultKafkaConsumerFactory<>(consumerProps); - Consumer consumer = cf.createConsumer(); - embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawJsonMapTopic); - - // Clarifying note (for Spring newbies): - // UdpServicesController is annotated with @Controller, and this test class is annotated with @SpringBootTest - // so a UdpServicesController will be instantiated before this test runs. That means the MapReceiver will also - // be instantiated and ready to consume UDP traffic from the same port we configure the TestUDPClient to send packets to. - TestUDPClient udpClient = new TestUDPClient(mapReceiverPort); - - for (ApprovalTestCase approvalTestCase : approvalTestCases) { - udpClient.send(approvalTestCase.getInput()); - - ConsumerRecord produced = KafkaTestUtils.getSingleRecord(consumer, rawJsonMapTopic); - - JSONObject producedJson = new JSONObject(produced.value()); - JSONObject expectedJson = new JSONObject(approvalTestCase.getExpected()); - - // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared - assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), producedJson.getJSONObject("metadata").get("serialId")); - expectedJson.getJSONObject("metadata").remove("serialId"); - producedJson.getJSONObject("metadata").remove("serialId"); - - assertEquals(expectedJson.toString(), producedJson.toString()); - } + + private final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + KafkaTemplate kafkaTemplate; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Test + void testMapReceiver() throws IOException { + + // Set the clock to a fixed time so that the MapReceiver will produce the same output every time + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2020-01-01T00:00:00Z"), Clock.systemUTC().getZone())); + // Set the static schema version to 7 so that the MapReceiver will produce the same output every time + // This is necessary because the schema version is set in only one of the OdeMsgMetadata constructors (this should be fixed) + // and the schema version is set to the static schema version in the constructor. This means that the schema version + // will be set to 6 for all OdeMsgMetadata objects created in the MapReceiver run method's code path. + OdeMsgMetadata.setStaticSchemaVersion(7); + + MapReceiver mapReceiver = new MapReceiver(udpReceiverProperties.getMap(), kafkaTemplate, + rawEncodedJsonTopics.getMap()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(mapReceiver); + + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getMap(), 1, (short) 1)); + } catch (Exception e) { + log.warn( + "Couldn't create topics. If the error indicates the topics already exist, this message is safe to ignore: {}", + e.getMessage()); + } + + // Set up a Kafka consumer + Map consumerProps = + KafkaTestUtils.consumerProps("test-group", "false", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getMap()); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getMap().getReceiverPort()); + + String path = + "src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json"; + List approvalTestCases = deserializeTestCases(path); + + for (ApprovalTestCase approvalTestCase : approvalTestCases) { + udpClient.send(approvalTestCase.getInput()); + + ConsumerRecord produced = + KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getMap()); + + JSONObject producedJson = new JSONObject(produced.value()); + JSONObject expectedJson = new JSONObject(approvalTestCase.getExpected()); + + // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals(expectedJson.toString(), producedJson.toString(), + approvalTestCase.getDescription()); } + } } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java new file mode 100644 index 000000000..d1b3f51ad --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java @@ -0,0 +1,105 @@ +package us.dot.its.jpo.ode.udp.psm; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.psm.receiver-port=15456", + "ode.kafka.topics.raw-encoded-json.psm=topic.PsmReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class PsmReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getPsm(), 1, (short) 1)); + } catch (Exception e) { + // Ignore as we're only ensuring topics exist + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + + PsmReceiver psmReceiver = new PsmReceiver(udpReceiverProperties.getPsm(), kafkaTemplate, + rawEncodedJsonTopics.getPsm()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(psmReceiver); + + String fileContent = + Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt")); + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getPsm().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "PsmReceiverTest", "true", embeddedKafka); + var cf = new DefaultKafkaConsumerFactory(consumerProps); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getPsm()); + + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getPsm()); + assertNotEquals(expected, singleRecord.value()); + + JSONObject producedJson = new JSONObject(singleRecord.value()); + JSONObject expectedJson = new JSONObject(expected); + + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals(expectedJson.toString(2), producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java new file mode 100644 index 000000000..8aa9abe84 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java @@ -0,0 +1,110 @@ +package us.dot.its.jpo.ode.udp.spat; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.Consumer; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.spat.receiver-port=15356", + "ode.kafka.topics.raw-encoded-json.spat=topic.SpatReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class SpatReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + private KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSpat(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topics exist not that they're unique + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + + SpatReceiver spatReceiver = new SpatReceiver(udpReceiverProperties.getSpat(), kafkaTemplate, + rawEncodedJsonTopics.getSpat()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(spatReceiver); + + String fileContent = + Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt")); + + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getSpat().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "SpatReceiverTest", "true", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getSpat()); + + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSpat()); + assertNotEquals(expected, singleRecord.value()); + JSONObject producedJson = new JSONObject(singleRecord.value()); + JSONObject expectedJson = new JSONObject(expected); + + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals( + expectedJson.toString(2), + producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java new file mode 100644 index 000000000..ea0723955 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java @@ -0,0 +1,108 @@ +package us.dot.its.jpo.ode.udp.srm; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.srm.receiver-port=15459", + "ode.kafka.topics.raw-encoded-json.srm=topic.SrmReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class SrmReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1)); + } catch (Exception e) { + // Ignore - ensure topic existence + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + + SrmReceiver srmReceiver = new SrmReceiver( + udpReceiverProperties.getSrm(), + kafkaTemplate, rawEncodedJsonTopics.getSrm() + ); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(srmReceiver); + + String fileContent = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt")); + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getSrm().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "SrmReceiverTest", "true", embeddedKafka); + var cf = new DefaultKafkaConsumerFactory(consumerProps); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getSrm()); + + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSrm()); + String receivedValue = singleRecord.value(); + assertNotEquals(expected, receivedValue); + + JSONObject producedJson = new JSONObject(receivedValue); + JSONObject expectedJson = new JSONObject(expected); + + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals(expectedJson.toString(2), producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java new file mode 100644 index 000000000..f8844d312 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java @@ -0,0 +1,108 @@ +package us.dot.its.jpo.ode.udp.ssm; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.Consumer; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.ssm.receiver-port=15358", + "ode.kafka.topics.raw-encoded-json.ssm=topic.SsmReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class SsmReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + try { + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSsm(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topics exist not that they're unique + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + + SsmReceiver ssmReceiver = new SsmReceiver(udpReceiverProperties.getSsm(), kafkaTemplate, + rawEncodedJsonTopics.getSsm()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(ssmReceiver); + + String fileContent = + Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt")); + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getSsm().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "SsmReceiverTest", "true", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getSsm()); + + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getSsm()); + assertNotEquals(expected, singleRecord.value()); + JSONObject producedJson = new JSONObject(singleRecord.value()); + JSONObject expectedJson = new JSONObject(expected); + + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals( + expectedJson.toString(2), + producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java new file mode 100644 index 000000000..e11f96254 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java @@ -0,0 +1,111 @@ +package us.dot.its.jpo.ode.udp.tim; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.apache.kafka.clients.admin.NewTopic; +import org.apache.kafka.clients.consumer.Consumer; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.test.utilities.TestUDPClient; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.util.DateTimeUtils; + +@RunWith(SpringRunner.class) +@EnableConfigurationProperties +@SpringBootTest( + classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, + properties = { + "ode.receivers.tim.receiver-port=15353", + "ode.kafka.topics.raw-encoded-json.tim=topic.TimReceiverTest" + } +) +@ContextConfiguration(classes = { + UDPReceiverProperties.class, OdeKafkaProperties.class, + RawEncodedJsonTopics.class, KafkaProperties.class +}) +class TimReceiverTest { + + @Autowired + UDPReceiverProperties udpReceiverProperties; + + @Autowired + RawEncodedJsonTopics rawEncodedJsonTopics; + + @Autowired + KafkaTemplate kafkaTemplate; + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + + @Test + void testRun() throws Exception { + try { + + embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getTim(), 1, (short) 1)); + } catch (Exception e) { + // ignore because we only care that the topics exist not that they're unique + } + + DateTimeUtils.setClock( + Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); + + TimReceiver timReceiver = new TimReceiver(udpReceiverProperties.getTim(), + kafkaTemplate, rawEncodedJsonTopics.getTim()); + ExecutorService executorService = Executors.newCachedThreadPool(); + executorService.submit(timReceiver); + + String fileContent = + Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt")); + String expected = Files.readString(Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json")); + + TestUDPClient udpClient = new TestUDPClient(udpReceiverProperties.getTim().getReceiverPort()); + udpClient.send(fileContent); + + var consumerProps = KafkaTestUtils.consumerProps( + "TimReceiverTest", "true", embeddedKafka); + DefaultKafkaConsumerFactory cf = + new DefaultKafkaConsumerFactory<>(consumerProps); + Consumer consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, rawEncodedJsonTopics.getTim()); + + var singleRecord = KafkaTestUtils.getSingleRecord(consumer, rawEncodedJsonTopics.getTim()); + // confirm the stream-id is different, then remove it from both so that we can test equality of all other fields + assertNotEquals(expected, singleRecord.value()); + JSONObject producedJson = new JSONObject(singleRecord.value()); + JSONObject expectedJson = new JSONObject(expected); + + // assert that the UUIDs are different, then remove them so that the rest of the JSON can be compared + assertNotEquals(expectedJson.getJSONObject("metadata").get("serialId"), + producedJson.getJSONObject("metadata").get("serialId")); + expectedJson.getJSONObject("metadata").remove("serialId"); + producedJson.getJSONObject("metadata").remove("serialId"); + + assertEquals( + expectedJson.toString(2), + producedJson.toString(2)); + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/application.yaml b/jpo-ode-svcs/src/test/resources/application.yaml index 9e9304c61..5bc494032 100644 --- a/jpo-ode-svcs/src/test/resources/application.yaml +++ b/jpo-ode-svcs/src/test/resources/application.yaml @@ -15,6 +15,8 @@ spring: group-id: test-group auto-offset-reset: earliest client-id: "ode-svcs-consumer" + admin: + auto-create: false ode: output-schema-version: 7 security-services: diff --git a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json index f9d965ce8..9214b1aa1 100644 --- a/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json +++ b/jpo-ode-svcs/src/test/resources/us.dot.its.jpo.ode.udp.map/UDPMAP_To_EncodedJSON_Validation.json @@ -19,14 +19,14 @@ }, "sanitized": false, "recordType": "mapTx", - "asn1": "0012303031323833423033383032333030303230343443343039344433453939423432434335454531443534323030324443333635383244323830303030303730303031423631353244453241303041304136433138444241343930313431344438304137373646323032383531414645423246313134303530353335453942313833333830413134323538333230303034303041343245303030323032323634303035383246323830303030303230303032393630464231453137354230343430463233363035303533363034444445333043304131343643303343424346393831343134443746353337384143303238323941463832304434423430353041333546353144433746383039463630353832413030303138303936304334413030303030303830303036353832373037383236364331384442413636303134323844383043463737374330323835314146443945454234303035304131354537323937443530313630383830303036303235383242303830303030303130303032333632373639453245383041304132424634323345313542363038313944323438304131343643303131424435323831343134443746354637383144303238323941464142364535334330353035303043353038303030344230373239303030303030323030303436424342413339463130313432384437384642383236303032374439414444394546443338303446313335364238314646413430413041324231444434303133393544453135464645383036333434303030323538333734383030303030313030303033354538344444334530304130413242443345433133333030433634383030303434303636433830303030303030364232423032423145383134313435374633433830413131303141423230303030303030314143433736414544413035303531354643433630323938423030433530303030303038303030343242454234334537304235433845444636443830394636324242333933463846423544423439464444383039463636414639344246463730313431343535454246383031313035383843303030313030393630303841303030303031303030303635374445443741323136424237443346324538313431344437314332374535323032374231414145413446454532303530353335363532453030323830394636303538394330303031303039363031304130303030303130303030363537443535374236373242393430334545373335444135354642463430394636324141443733464242313536443932303039433136323530303030343032323032324334303030303030303136313830394642363042303146423030374532303234433430303030303030313631393444463538434230323133303042383230323643343030303030303031363142373545463735423031464230304130303530353038303431313030303030303030443737323338363539303237423041464439324646384532303045343430303030303030333544444132313433343039454332424635393346453038383033313130303030303030304437374334383339323032374230414644314546463845323030413434303030303030303335444645323038443030394543324246344142464444383830323131303030303030303044373834393830433530323742304146443134464636303538313236383030303030313030303042354535344132393434303945433242463330433346443135464239413038313035363130343030303830324230373230303034303232433041333430303030303038303030354146353537313533363034464233354638373232303434303946363242464235343130383032433138383030313030383430324430383030303030303036424544414335374538313345433537464242383045423243304335343030303030323830303044423034313131323043303446423136324645323041304442324441313036463230353035313633374645303539314231413033303139453035303530414332323030303138303432313634303035383141413830303030303430303031333630393445314541303039463632433931313431424642363444363630423143304130413643424632433130323031343134304230373830303036303132433045353430303030303230303031354230353331304341383034464231363338324130413935423142463330343743303530353136323545453034443442313241373031454335383938413830414336433235443430323830313431343042303638303030363031324330463534303030303032303030304442303542393039444530344642333635433836313043343041304132433731304330454531363235444130334331423143354630314636303530353032433136303030313830344230343135303030303030383030303332433139303431424631363337464530414143423234464630354136353845323138313830364337313443303743383134313430423034383030303630313130313437323030303030303031423431314546453434303530353136303343413030354330303000", + "asn1": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000", "maxDurationTime": 0, "odeReceivedAt": "2020-01-01T00:00:00.000Z", "originIp": "127.0.0.1" }, "payload": { "data": { - "bytes": "0012303031323833423033383032333030303230343443343039344433453939423432434335454531443534323030324443333635383244323830303030303730303031423631353244453241303041304136433138444241343930313431344438304137373646323032383531414645423246313134303530353335453942313833333830413134323538333230303034303041343245303030323032323634303035383246323830303030303230303032393630464231453137354230343430463233363035303533363034444445333043304131343643303343424346393831343134443746353337384143303238323941463832304434423430353041333546353144433746383039463630353832413030303138303936304334413030303030303830303036353832373037383236364331384442413636303134323844383043463737374330323835314146443945454234303035304131354537323937443530313630383830303036303235383242303830303030303130303032333632373639453245383041304132424634323345313542363038313944323438304131343643303131424435323831343134443746354637383144303238323941464142364535334330353035303043353038303030344230373239303030303030323030303436424342413339463130313432384437384642383236303032374439414444394546443338303446313335364238314646413430413041324231444434303133393544453135464645383036333434303030323538333734383030303030313030303033354538344444334530304130413242443345433133333030433634383030303434303636433830303030303030364232423032423145383134313435374633433830413131303141423230303030303030314143433736414544413035303531354643433630323938423030433530303030303038303030343242454234334537304235433845444636443830394636324242333933463846423544423439464444383039463636414639344246463730313431343535454246383031313035383843303030313030393630303841303030303031303030303635374445443741323136424237443346324538313431344437314332374535323032374231414145413446454532303530353335363532453030323830394636303538394330303031303039363031304130303030303130303030363537443535374236373242393430334545373335444135354642463430394636324141443733464242313536443932303039433136323530303030343032323032324334303030303030303136313830394642363042303146423030374532303234433430303030303030313631393444463538434230323133303042383230323643343030303030303031363142373545463735423031464230304130303530353038303431313030303030303030443737323338363539303237423041464439324646384532303045343430303030303030333544444132313433343039454332424635393346453038383033313130303030303030304437374334383339323032374230414644314546463845323030413434303030303030303335444645323038443030394543324246344142464444383830323131303030303030303044373834393830433530323742304146443134464636303538313236383030303030313030303042354535344132393434303945433242463330433346443135464239413038313035363130343030303830324230373230303034303232433041333430303030303038303030354146353537313533363034464233354638373232303434303946363242464235343130383032433138383030313030383430324430383030303030303036424544414335374538313345433537464242383045423243304335343030303030323830303044423034313131323043303446423136324645323041304442324441313036463230353035313633374645303539314231413033303139453035303530414332323030303138303432313634303035383141413830303030303430303031333630393445314541303039463632433931313431424642363444363630423143304130413643424632433130323031343134304230373830303036303132433045353430303030303230303031354230353331304341383034464231363338324130413935423142463330343743303530353136323545453034443442313241373031454335383938413830414336433235443430323830313431343042303638303030363031324330463534303030303032303030304442303542393039444530344642333635433836313043343041304132433731304330454531363235444130334331423143354630314636303530353032433136303030313830344230343135303030303030383030303332433139303431424631363337464530414143423234464630354136353845323138313830364337313443303743383134313430423034383030303630313130313437323030303030303031423431314546453434303530353136303343413030354330303000" + "bytes": "001283B0380230002044C4094D3E99B42CC5EE1D542002DC36582D280000070001B6152DE2A00A0A6C18DBA4901414D80A776F202851AFEB2F114050535E9B183380A1425832000400A42E00020226400582F280000020002960FB1E175B0440F23605053604DDE30C0A146C03CBCF981414D7F5378AC02829AF820D4B4050A35F51DC7F809F60582A000180960C4A000000800065827078266C18DBA6601428D80CF777C02851AFD9EEB40050A15E7297D5016088000602582B080000010002362769E2E80A0A2BF423E15B60819D2480A146C011BD5281414D7F5F781D02829AFAB6E53C050500C5080004B0729000000200046BCBA39F101428D78FB8260027D9ADD9EFD3804F1356B81FFA40A0A2B1DD401395DE15FFE8063440002583748000001000035E84DD3E00A0A2BD3EC13300C64800044066C800000006B2B02B1E8141457F3C80A1101AB200000001ACC76AEDA050515FCC60298B00C5000000800042BEB43E70B5C8EDF6D809F62BB393F8FB5DB49FDD809F66AF94BFF70141455EBF80110588C00010096008A0000010000657DED7A216BB7D3F2E81414D71C27E52027B1AAEA4FEE2050535652E002809F60589C00010096010A0000010000657D557B672B9403EE735DA55FBF409F62AAD73FBB156D92009C162500004022022C40000000161809FB60B01FB007E2024C4000000016194DF58CB021300B82026C40000000161B75EF75B01FB00A0050508041100000000D77238659027B0AFD92FF8E200E44000000035DDA2143409EC2BF593FE088031100000000D77C48392027B0AFD1EFF8E200A44000000035DFE208D009EC2BF4ABFDD88021100000000D784980C5027B0AFD14FF605812680000010000B5E54A294409EC2BF30C3FD15FB9A081056104000802B0720004022C0A3400000080005AF557153604FB35F872204409F62BFB5410802C188001008402D0800000006BEDAC57E813EC57FBB80EB2C0C540000028000DB0411120C04FB162FE20A0DB2DA106F205051637FE0591B1A03019E05050AC220001804216400581AA8000004000136094E1EA009F62C91141BFB64D660B1C0A0A6CBF2C102014140B0780006012C0E5400000200015B05310CA804FB16382A0A95B1BF3047C05051625EE04D4B12A701EC5898A80AC6C25D4028014140B0680006012C0F540000020000DB05B909DE04FB365C8610C40A0A2C710C0EE1625DA03C1B1C5F01F6050502C160001804B0415000000800032C19041BF1637FE0AACB24FF05A658E2181806C714C07C814140B04800060110147200000001B411EFE4405051603CA005C000" }, "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray" } @@ -51,14 +51,14 @@ }, "sanitized": false, "recordType": "mapTx", - "asn1": "001230303132376232323664363537343631363436313734363132323361376232323733363536333735373236393734373935323635373337353663373434333666363436353232336132323733373536333633363537333733323232633232373236353633366637323634343736353665363537323631373436353634343237393232336136653735366336633263323237333633363836353664363135363635373237333639366636653232336133363263323236663634363535303631363336623635373434393434323233613232323232633232373336313665363937343639376136353634323233613636363136633733363532633232373236353633366637323634353437393730363532323361323236643631373035343738323232633232363536653633366636343639366536373733323233613665373536633663326332323732363536333666373236343437363536653635373236313734363536343431373432323361323232323263323236643631373834343735373236313734363936663665353436393664363532323361333032633232366636343635353436393664353337343631373237343434363137343635353436393664363532323361323232323263323237323635363336353639373636353634346436353733373336313637363534343635373436313639366337333232336137623232366336663633363137343639366636653434363137343631323233613665373536633663326332323732373835333666373537323633363532323361323234653431323237643263323236643631373035333666373537323633363532323361323235323533353532323263323237303631373936633666363136343534373937303635323233613232373537333265363436663734326536393734373332653661373036663265366636343635326536643666363436353663326534663634363534643631373035303631373936633666363136343232326332323733363537323639363136633439363432323361376232323732363536333666373236343439363432323361333032633232373336353732363936313663346537353664363236353732323233613330326332323733373437323635363136643439363432323361323233313333333936323631333336313636326436353335333033313264333433383335333432643339333333323337326436323339363533313631333236353634333836343636363232323263323236323735366536343663363535333639376136353232336133313263323236323735366536343663363534393634323233613330376432633232366336663637343636393663363534653631366436353232336132323232326332323666363436353532363536333635363937363635363434313734323233613232343034393533346635663434343135343435356635343439346434353430323232633232366637323639363736393665343937303232336132323331333032653331333132653338333132653331333232323764326332323730363137393663366636313634323233613762323236343631373436313232336137623232373436393664363535333734363136643730323233613665373536633663326332323663363137393635373235343739373036353232336132323639366537343635373237333635363337343639366636653434363137343631323232633232366336313739363537323439343432323361333032633232373236353733373437323639363337343639366636653463363937333734323233613665373536633663326332323634363137343631353036313732363136643635373436353732373332323361366537353663366332633232366437333637343937333733373536353532363537363639373336393666366532323361333232633232363936653734363537323733363536333734363936663665373332323361376232323639366537343635373237333635363337343639366636653437363536663664363537343732373932323361356237623232373337303635363536343463363936643639373437333232336136653735366336633263323236633631366536353533363537343232336137623232343736353665363537323639363334633631366536353232336135623762323236333666366536653635363337343733353436663232336137623232363336663665366536353633373437333534366632323361356237623232373537333635373234333663363137333733323233613665373536633663326332323633366636653665363536333734363936663665343934343232336133313263323237323635366436663734363534393665373436353732373336353633373436393666366532323361366537353663366332633232373336393637366536313663343737323666373537303232336133323263323236333666366536653635363337343639366536373463363136653635323233613762323236633631366536353232336133313335326332323664363136653635373537363635373232323361376232323664363136653635373537363635373235333734373236313639363736383734343136633663366637373635363432323361373437323735363532633232366436313665363537353736363537323465366635333734366637303730363936653637343136633663366637373635363432323361363636313663373336353263323236373666353736393734363834383631366337343232336136363631366300", + "asn1": "00127B226D65746164617461223A7B227365637572697479526573756C74436F6465223A2273756363657373222C227265636F726447656E6572617465644279223A6E756C6C2C22736368656D6156657273696F6E223A362C226F64655061636B65744944223A22222C2273616E6974697A6564223A66616C73652C227265636F726454797065223A226D61705478222C22656E636F64696E6773223A6E756C6C2C227265636F726447656E6572617465644174223A22222C226D61784475726174696F6E54696D65223A302C226F646554696D53746172744461746554696D65223A22222C2272656365697665644D65737361676544657461696C73223A7B226C6F636174696F6E44617461223A6E756C6C2C227278536F75726365223A224E41227D2C226D6170536F75726365223A22525355222C227061796C6F616454797065223A2275732E646F742E6974732E6A706F2E6F64652E6D6F64656C2E4F64654D61705061796C6F6164222C2273657269616C4964223A7B227265636F72644964223A302C2273657269616C4E756D626572223A302C2273747265616D4964223A2231333962613361662D653530312D343835342D393332372D623965316132656438646662222C2262756E646C6553697A65223A312C2262756E646C654964223A307D2C226C6F6746696C654E616D65223A22222C226F646552656365697665644174223A224049534F5F444154455F54494D4540222C226F726967696E4970223A2231302E31312E38312E3132227D2C227061796C6F6164223A7B2264617461223A7B2274696D655374616D70223A6E756C6C2C226C6179657254797065223A22696E74657273656374696F6E44617461222C226C617965724944223A302C227265737472696374696F6E4C697374223A6E756C6C2C2264617461506172616D6574657273223A6E756C6C2C226D736749737375655265766973696F6E223A322C22696E74657273656374696F6E73223A7B22696E74657273656374696F6E47656F6D65747279223A5B7B2273706565644C696D697473223A6E756C6C2C226C616E65536574223A7B2247656E657269634C616E65223A5B7B22636F6E6E65637473546F223A7B22636F6E6E65637473546F223A5B7B2275736572436C617373223A6E756C6C2C22636F6E6E656374696F6E4944223A312C2272656D6F7465496E74657273656374696F6E223A6E756C6C2C227369676E616C47726F7570223A322C22636F6E6E656374696E674C616E65223A7B226C616E65223A31352C226D616E6575766572223A7B226D616E65757665725374726169676874416C6C6F776564223A747275652C226D616E65757665724E6F53746F7070696E67416C6C6F776564223A66616C73652C22676F5769746848616C74223A66616C73652C226D616E65757665724C656674416C6C6F776564223A66616C73652C226D616E6575766572555475726E416C6C6F776564223A66616C73652C226D616E65757665724C6566745475726E4F6E526564416C6C6F776564223A66616C73652C22726573657276656431223A66616C73652C226D616E65757665725269676874416C6C6F776564223A66616C73652C226D616E65757665724C616E654368616E6765416C6C6F776564223A66616C73652C227969656C64416C6C776179735265717569726564223A66616C73652C226D616E657576657252696768745475726E4F6E526564416C6C6F776564223A66616C73652C2263617574696F6E223A66616C73657D7D7D5D7D2C226C616E654944223A312C22656772657373417070726F616368223A6E756C6C2C226C616E6541747472696275746573223A7B22646972656374696F6E616C557365223A7B22696E677265737350617468223A747275652C2265677265737350617468223A66616C73657D2C22736861726557697468223A7B2262757356656869636C6554726166666963223A66616C73652C22747261636B656456656869636C6554726166666963223A66616C73652C22696E646976696475616C4D6F746F72697A656456656869636C6554726166666963223A66616C73652C227461786956656869636C6554726166666963223A66616C73652C226F7665726C617070696E674C616E654465736372697074696F6E50726F7669646564223A66616C73652C226379636C69737456656869636C6554726166666963223A66616C73652C226F746865724E6F6E4D6F746F72697A6564547261666669635479706573223A66616C73652C226D756C7469706C654C616E65735472656174656441734F6E654C616E65223A66616C73652C227065646573747269616E54726166666963223A66616C73652C227065646573747269616E7354726166666963223A66616C73657D2C226C616E6554797065223A7B227369646577616C6B223A6E756C6C2C227061726B696E67223A6E756C6C2C2263726F737377616C6B223A6E756C6C2C226D656469616E223A6E756C6C2C227374726970696E67223A6E756C6C2C2262696B654C616E65223A6E756C6C2C22747261636B656456656869636C65223A6E756C6C2C2276656869636C65223A7B22697356656869636C655265766F6361626C654C616E65223A66616C73652C22697356656869636C65466C794F7665724C616E65223A66616C73652C227065726D697373696F6E4F6E52657175657374223A66616C73652C226861734952626561636F6E436F766572616765223A66616C73652C2272657374726963746564546F427573557365223A66616C73652C2272657374726963746564546F54617869557365223A66616C73652C00", "maxDurationTime": 0, "odeReceivedAt": "2020-01-01T00:00:00.000Z", "originIp": "127.0.0.1" }, "payload": { "data": { - "bytes": "001230303132376232323664363537343631363436313734363132323361376232323733363536333735373236393734373935323635373337353663373434333666363436353232336132323733373536333633363537333733323232633232373236353633366637323634343736353665363537323631373436353634343237393232336136653735366336633263323237333633363836353664363135363635373237333639366636653232336133363263323236663634363535303631363336623635373434393434323233613232323232633232373336313665363937343639376136353634323233613636363136633733363532633232373236353633366637323634353437393730363532323361323236643631373035343738323232633232363536653633366636343639366536373733323233613665373536633663326332323732363536333666373236343437363536653635373236313734363536343431373432323361323232323263323236643631373834343735373236313734363936663665353436393664363532323361333032633232366636343635353436393664353337343631373237343434363137343635353436393664363532323361323232323263323237323635363336353639373636353634346436353733373336313637363534343635373436313639366337333232336137623232366336663633363137343639366636653434363137343631323233613665373536633663326332323732373835333666373537323633363532323361323234653431323237643263323236643631373035333666373537323633363532323361323235323533353532323263323237303631373936633666363136343534373937303635323233613232373537333265363436663734326536393734373332653661373036663265366636343635326536643666363436353663326534663634363534643631373035303631373936633666363136343232326332323733363537323639363136633439363432323361376232323732363536333666373236343439363432323361333032633232373336353732363936313663346537353664363236353732323233613330326332323733373437323635363136643439363432323361323233313333333936323631333336313636326436353335333033313264333433383335333432643339333333323337326436323339363533313631333236353634333836343636363232323263323236323735366536343663363535333639376136353232336133313263323236323735366536343663363534393634323233613330376432633232366336663637343636393663363534653631366436353232336132323232326332323666363436353532363536333635363937363635363434313734323233613232343034393533346635663434343135343435356635343439346434353430323232633232366637323639363736393665343937303232336132323331333032653331333132653338333132653331333232323764326332323730363137393663366636313634323233613762323236343631373436313232336137623232373436393664363535333734363136643730323233613665373536633663326332323663363137393635373235343739373036353232336132323639366537343635373237333635363337343639366636653434363137343631323232633232366336313739363537323439343432323361333032633232373236353733373437323639363337343639366636653463363937333734323233613665373536633663326332323634363137343631353036313732363136643635373436353732373332323361366537353663366332633232366437333637343937333733373536353532363537363639373336393666366532323361333232633232363936653734363537323733363536333734363936663665373332323361376232323639366537343635373237333635363337343639366636653437363536663664363537343732373932323361356237623232373337303635363536343463363936643639373437333232336136653735366336633263323236633631366536353533363537343232336137623232343736353665363537323639363334633631366536353232336135623762323236333666366536653635363337343733353436663232336137623232363336663665366536353633373437333534366632323361356237623232373537333635373234333663363137333733323233613665373536633663326332323633366636653665363536333734363936663665343934343232336133313263323237323635366436663734363534393665373436353732373336353633373436393666366532323361366537353663366332633232373336393637366536313663343737323666373537303232336133323263323236333666366536653635363337343639366536373463363136653635323233613762323236633631366536353232336133313335326332323664363136653635373537363635373232323361376232323664363136653635373537363635373235333734373236313639363736383734343136633663366637373635363432323361373437323735363532633232366436313665363537353736363537323465366635333734366637303730363936653637343136633663366637373635363432323361363636313663373336353263323236373666353736393734363834383631366337343232336136363631366300" + "bytes": "00127B226D65746164617461223A7B227365637572697479526573756C74436F6465223A2273756363657373222C227265636F726447656E6572617465644279223A6E756C6C2C22736368656D6156657273696F6E223A362C226F64655061636B65744944223A22222C2273616E6974697A6564223A66616C73652C227265636F726454797065223A226D61705478222C22656E636F64696E6773223A6E756C6C2C227265636F726447656E6572617465644174223A22222C226D61784475726174696F6E54696D65223A302C226F646554696D53746172744461746554696D65223A22222C2272656365697665644D65737361676544657461696C73223A7B226C6F636174696F6E44617461223A6E756C6C2C227278536F75726365223A224E41227D2C226D6170536F75726365223A22525355222C227061796C6F616454797065223A2275732E646F742E6974732E6A706F2E6F64652E6D6F64656C2E4F64654D61705061796C6F6164222C2273657269616C4964223A7B227265636F72644964223A302C2273657269616C4E756D626572223A302C2273747265616D4964223A2231333962613361662D653530312D343835342D393332372D623965316132656438646662222C2262756E646C6553697A65223A312C2262756E646C654964223A307D2C226C6F6746696C654E616D65223A22222C226F646552656365697665644174223A224049534F5F444154455F54494D4540222C226F726967696E4970223A2231302E31312E38312E3132227D2C227061796C6F6164223A7B2264617461223A7B2274696D655374616D70223A6E756C6C2C226C6179657254797065223A22696E74657273656374696F6E44617461222C226C617965724944223A302C227265737472696374696F6E4C697374223A6E756C6C2C2264617461506172616D6574657273223A6E756C6C2C226D736749737375655265766973696F6E223A322C22696E74657273656374696F6E73223A7B22696E74657273656374696F6E47656F6D65747279223A5B7B2273706565644C696D697473223A6E756C6C2C226C616E65536574223A7B2247656E657269634C616E65223A5B7B22636F6E6E65637473546F223A7B22636F6E6E65637473546F223A5B7B2275736572436C617373223A6E756C6C2C22636F6E6E656374696F6E4944223A312C2272656D6F7465496E74657273656374696F6E223A6E756C6C2C227369676E616C47726F7570223A322C22636F6E6E656374696E674C616E65223A7B226C616E65223A31352C226D616E6575766572223A7B226D616E65757665725374726169676874416C6C6F776564223A747275652C226D616E65757665724E6F53746F7070696E67416C6C6F776564223A66616C73652C22676F5769746848616C74223A66616C73652C226D616E65757665724C656674416C6C6F776564223A66616C73652C226D616E6575766572555475726E416C6C6F776564223A66616C73652C226D616E65757665724C6566745475726E4F6E526564416C6C6F776564223A66616C73652C22726573657276656431223A66616C73652C226D616E65757665725269676874416C6C6F776564223A66616C73652C226D616E65757665724C616E654368616E6765416C6C6F776564223A66616C73652C227969656C64416C6C776179735265717569726564223A66616C73652C226D616E657576657252696768745475726E4F6E526564416C6C6F776564223A66616C73652C2263617574696F6E223A66616C73657D7D7D5D7D2C226C616E654944223A312C22656772657373417070726F616368223A6E756C6C2C226C616E6541747472696275746573223A7B22646972656374696F6E616C557365223A7B22696E677265737350617468223A747275652C2265677265737350617468223A66616C73657D2C22736861726557697468223A7B2262757356656869636C6554726166666963223A66616C73652C22747261636B656456656869636C6554726166666963223A66616C73652C22696E646976696475616C4D6F746F72697A656456656869636C6554726166666963223A66616C73652C227461786956656869636C6554726166666963223A66616C73652C226F7665726C617070696E674C616E654465736372697074696F6E50726F7669646564223A66616C73652C226379636C69737456656869636C6554726166666963223A66616C73652C226F746865724E6F6E4D6F746F72697A6564547261666669635479706573223A66616C73652C226D756C7469706C654C616E65735472656174656441734F6E654C616E65223A66616C73652C227065646573747269616E54726166666963223A66616C73652C227065646573747269616E7354726166666963223A66616C73657D2C226C616E6554797065223A7B227369646577616C6B223A6E756C6C2C227061726B696E67223A6E756C6C2C2263726F737377616C6B223A6E756C6C2C226D656469616E223A6E756C6C2C227374726970696E67223A6E756C6C2C2262696B654C616E65223A6E756C6C2C22747261636B656456656869636C65223A6E756C6C2C2276656869636C65223A7B22697356656869636C655265766F6361626C654C616E65223A66616C73652C22697356656869636C65466C794F7665724C616E65223A66616C73652C227065726D697373696F6E4F6E52657175657374223A66616C73652C226861734952626561636F6E436F766572616765223A66616C73652C2272657374726963746564546F427573557365223A66616C73652C2272657374726963746564546F54617869557365223A66616C73652C00" }, "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray" } diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt new file mode 100644 index 000000000..dcac543c5 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM.txt @@ -0,0 +1 @@ +0022e12d18466c65c1493800000e00e4616183e85a8f0100c000038081bc001480b8494c4c950cd8cde6e9651116579f22a424dd78fffff00761e4fd7eb7d07f7fff80005f11d1020214c1c0ffc7c016aff4017a0ff65403b0fd204c20ffccc04f8fe40c420ffe6404cefe60e9a10133408fcfde1438103ab4138f00e1eec1048ec160103e237410445c171104e26bc103dc4154305c2c84103b1c1c8f0a82f42103f34262d1123198103dac25fb12034ce10381c259f12038ca103574251b10e3b2210324c23ad0f23d8efffe0000209340d10000004264bf00 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json new file mode 100644 index 000000000..3b7345c27 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest_ValidBSM_expected.json @@ -0,0 +1,38 @@ +{ + "metadata": { + "bsmSource": "EV", + "recordType": "bsmTx", + "securityResultCode": "success", + "receivedMessageDetails": { + "locationData": { + "latitude": "unavailable", + "longitude": "unavailable", + "elevation": "unavailable", + "speed": "unavailable", + "heading": "unavailable" + }, + "rxSource": "RSU" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "de02c4a6-9ae3-4417-8bbc-636119ac0767", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-26T23:53:21.120Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "OBU", + "sanitized": false, + "asn1": "001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00", + "originIp": "127.0.0.1" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00" + } + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP.txt new file mode 100644 index 000000000..30fe576df --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP.txt @@ -0,0 +1 @@ +001283c138003000205e9c014d3eab092ca624b5518202dc3658042800000400023622c60ca009f66d48abfaf81388d8ad18070027d9b2ffcfe9804f13667b1ffd009ec2c76e3ffc82c4e0001004b00c5000000800066c4574101813ecd8b757fae027d9b30e6ff5604ec363561fe7809ec6cd69bfec813c4d8a617fc9027d9b2147008604fb163666000016250000802580228000001000096229e1309b51a6fe4204dd361cf1fe5009f6018e1000096020a00000080004d88a57f84027d9b3827002804ec36087600a009f62c289407282c310001c0440188800000006c46dbe02813ec5816d800710052200000001b11b6fad404fb16054a0000401c8800000006c47b3d24813ec5816d801b100c4200000000af890f12c580007e87100d4200000008af4c0f12c580077e7a2c0004000160002001cb028d000000800052c160bc40b5fffd8a9409d86bfebb5b40141457fef53b76c008b467014145800080002bffcbffc82c6a0001804b024d000000800036c2213c3b013ecd80096d64027d9affd8cdfc04f635ff7983bc09f66c0082aa2014280b1b80006012c0b3400000100004b02bcf0f6d7fe065d602788b0138eb900b1240001012c083400000080009b0c2af0b804fb15fe6de171afff6c63e04ec15fe1de670060e40002581ea8000004000135da6df0180a0a6adc2c00d0143cd51897fda028c8abb25001a0b0680008012c105400000200009aedbefae005053540ee003c0a326a9cf3fed8143c5667780010582c0004009608aa00000080004d76de7ee402829aba88ffdc050f354525fff80a322bcf23fa602c690000c04b0395000000200016bb4fbd4e01414d3215800802940ab108fff2030d2000110126200000001aee5103be050a15f6f1ffc8404d8800000006bb97c18e0142857dfa800010146200000001aee89099a050a15f8720000b05dd000000800046be3743b781428d80e1b00002879b00514b4404f63600827d8c09e22c000400015ffe6007016190000402582ce8000004000135ecee1de80a146c02e54758143cd8059ad3e027b1b00613dd004f102c360000804b055d000000200046bcc7c3c781428d80108c6e02829b002b2ece050a16019a4b29b00ab5c3604f136004e410409ec018a10000960c3a00000080004d7de9878602851b003923cc05053601623b440a0a6bfb8c3a5014140b0640005012c197400000100005afe570ef2050a36003a47c80a0a6bfd2c45f014140b054000501101a8200000001b05a90edc050535ffe605800a0a101b8200000001b08a30ec0050535ffe605300a0a101c8200000005b0c6f0ea4050515ffca0568b0001000e \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP_expected.json new file mode 100644 index 000000000..36945c4eb --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/map/MapReceiverTest_ValidMAP_expected.json @@ -0,0 +1,28 @@ +{ + "metadata" : { + "recordType" : "mapTx", + "securityResultCode" : "success", + "payloadType" : "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId" : { + "streamId" : "f32a9c67-1b6c-4835-b69f-ae2eacc5caea", + "bundleSize" : 1, + "bundleId" : 0, + "recordId" : 0, + "serialNumber" : 0 + }, + "odeReceivedAt": "2024-11-26T23:53:21.120Z", + "schemaVersion" : 7, + "maxDurationTime" : 0, + "recordGeneratedBy" : "RSU", + "sanitized" : false, + "asn1" : "001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E00", + "mapSource" : "RSU", + "originIp" : "127.0.0.1" + }, + "payload" : { + "dataType" : "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data" : { + "bytes" : "001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E00" + } + } +} diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt new file mode 100644 index 000000000..7a9270e7e --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM.txt @@ -0,0 +1 @@ +011d0000201a0000021bd86891de75f84da101c13f042e2214141fff00022c2000270000000163b2cc7986010000 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json new file mode 100644 index 000000000..4c53d160d --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest_ValidPSM_expected.json @@ -0,0 +1,28 @@ +{ + "metadata" : { + "recordType" : "psmTx", + "securityResultCode" : "success", + "payloadType" : "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId" : { + "streamId" : "33efc65d-f138-4c77-972c-1584d936e63e", + "bundleSize" : 1, + "bundleId" : 0, + "recordId" : 0, + "serialNumber" : 0 + }, + "odeReceivedAt" : "2024-11-26T23:53:21.120Z", + "schemaVersion" : 7, + "maxDurationTime" : 0, + "recordGeneratedBy" : "UNKNOWN", + "sanitized" : false, + "asn1" : "00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100", + "psmSource" : "RSU", + "originIp" : "127.0.0.1" + }, + "payload" : { + "dataType" : "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data" : { + "bytes" : "00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100" + } + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt new file mode 100644 index 000000000..ee8384cb7 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT.txt @@ -0,0 +1 @@ +001338000817a780000089680500204642b342b34802021a15a955a940181190acd0acd20100868555c555c00104342aae2aae002821a155715570 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json new file mode 100644 index 000000000..5602460b0 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest_ValidSPAT_expected.json @@ -0,0 +1,29 @@ +{ + "metadata" : { + "recordType" : "spatTx", + "securityResultCode" : "success", + "payloadType" : "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId" : { + "streamId" : "38337a4b-9972-4c9e-86dd-ce18c4d0830c", + "bundleSize" : 1, + "bundleId" : 0, + "recordId" : 0, + "serialNumber" : 0 + }, + "odeReceivedAt" : "2024-11-26T23:53:21.120Z", + "schemaVersion" : 7, + "maxDurationTime" : 0, + "recordGeneratedBy" : "RSU", + "sanitized" : false, + "asn1" : "001338000817A780000089680500204642B342B34802021A15A955A940181190ACD0ACD20100868555C555C00104342AAE2AAE002821A15571557000", + "spatSource" : "RSU", + "originIp" : "127.0.0.1", + "isCertPresent" : false + }, + "payload" : { + "dataType" : "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data" : { + "bytes" : "001338000817A780000089680500204642B342B34802021A15A955A940181190ACD0ACD20100868555C555C00104342AAE2AAE002821A15571557000" + } + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json new file mode 100644 index 000000000..17e87d5f6 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json @@ -0,0 +1,28 @@ +{ + "metadata" : { + "securityResultCode" : "success", + "recordGeneratedBy" : "OBU", + "schemaVersion" : 7, + "payloadType" : "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId" : { + "recordId" : 0, + "serialNumber" : 0, + "streamId" : "40fcefc3-0b58-4b8d-aff1-624afad55951", + "bundleSize" : 1, + "bundleId" : 0 + }, + "sanitized" : false, + "recordType" : "srmTx", + "asn1" : "001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000", + "srmSource" : "RSU", + "maxDurationTime" : 0, + "odeReceivedAt": "2024-11-26T23:53:21.120Z", + "originIp" : "127.0.0.1" + }, + "payload" : { + "data" : { + "bytes" : "001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000" + }, + "dataType" : "us.dot.its.jpo.ode.model.OdeHexByteArray" + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt new file mode 100644 index 000000000..865085205 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt @@ -0,0 +1 @@ +001d2130000010090bd341080d00855c6c0c6899853000a534f7c24cb29897694759b7c0 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt new file mode 100644 index 000000000..e05e4fd40 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM.txt @@ -0,0 +1 @@ +001e120000000005e9c04071a26614c06000040ba0 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json new file mode 100644 index 000000000..32881d799 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest_ValidSSM_expected.json @@ -0,0 +1,28 @@ +{ + "metadata": { + "recordType": "ssmTx", + "securityResultCode": "success", + "payloadType": "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId": { + "streamId": "db41bd96-51f6-40d7-a395-dee198042e5a", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-11-26T23:53:21.120Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedBy": "RSU", + "sanitized": false, + "asn1": "001E120000000005E9C04071A26614C06000040BA000", + "originIp": "127.0.0.1", + "ssmSource": "RSU" + }, + "payload": { + "dataType": "us.dot.its.jpo.ode.model.OdeHexByteArray", + "data": { + "bytes": "001E120000000005E9C04071A26614C06000040BA000" + } + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt new file mode 100644 index 000000000..b428028ec --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM.txt @@ -0,0 +1 @@ +001F80A97014B901EC9C236B00000000000F775D9B0301EA73E452D1539716C99E9D555100003F0A59B080010007F8AA9979F4D3BB3A0A9266C000000854E3B2C47291F21E85EEF057980028422C1FFE0001FFFC00017FFF80000FFFFF000009FFFFF8000005FFFFFF00000007FF80007FFF00005FFFE00003FFFFC000027FFFFE0000017FFFFFC000000C523E43D138ECB11C6200C00FB0473DFB72A0E997C74007D408E5C376CD4F775D9B00 \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json new file mode 100644 index 000000000..51f34623f --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/udp/tim/TimReceiverTest_ValidTIM_expected.json @@ -0,0 +1,27 @@ +{ + "metadata" : { + "securityResultCode" : "success", + "recordGeneratedBy" : "RSU", + "schemaVersion" : 7, + "payloadType" : "us.dot.its.jpo.ode.model.OdeAsn1Payload", + "serialId" : { + "recordId" : 0, + "serialNumber" : 0, + "streamId" : "8006adcf-9fd7-447a-9d02-33005f703d08", + "bundleSize" : 1, + "bundleId" : 0 + }, + "sanitized" : false, + "recordType" : "timMsg", + "asn1" : "001F80A97014B901EC9C236B00000000000F775D9B0301EA73E452D1539716C99E9D555100003F0A59B080010007F8AA9979F4D3BB3A0A9266C000000854E3B2C47291F21E85EEF057980028422C1FFE0001FFFC00017FFF80000FFFFF000009FFFFF8000005FFFFFF00000007FF80007FFF00005FFFE00003FFFFC000027FFFFE0000017FFFFFC000000C523E43D138ECB11C6200C00FB0473DFB72A0E997C74007D408E5C376CD4F775D9B00", + "maxDurationTime" : 0, + "odeReceivedAt" : "2024-11-26T23:53:21.120Z", + "originIp" : "127.0.0.1" + }, + "payload" : { + "data" : { + "bytes" : "001F80A97014B901EC9C236B00000000000F775D9B0301EA73E452D1539716C99E9D555100003F0A59B080010007F8AA9979F4D3BB3A0A9266C000000854E3B2C47291F21E85EEF057980028422C1FFE0001FFFC00017FFF80000FFFFF000009FFFFF8000005FFFFFF00000007FF80007FFF00005FFFE00003FFFFC000027FFFFE0000017FFFFFC000000C523E43D138ECB11C6200C00FB0473DFB72A0E997C74007D408E5C376CD4F775D9B00" + }, + "dataType" : "us.dot.its.jpo.ode.model.OdeHexByteArray" + } +} \ No newline at end of file From e03605eeede4bef50ca5842ee46dfb1f49d494fc Mon Sep 17 00:00:00 2001 From: Matt Cook Date: Fri, 13 Dec 2024 16:18:22 -0700 Subject: [PATCH 152/264] Migrate Asn1DecodedDataRouter to use Spring Kafka (#131) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore:delete disabled Asn1DecodedDataRouterTest Deleting these disabled tests to reduce confusion in future. They have been disabled for a long time, and they're mocking most data to the point of uselessness, so they are getting removed. * style: rename approval test to specify MAP data flow * test: add failing tests for each data flow in Asn1 decoded data routing * test: added test decoder-output-tim.xml test data This was generated by running data from `udpsender_tim.py` through the system locally and grabbing the value produced to `topic.Asn1DecoderOutput` Signed-off-by: Matt Cook * test: added test decoder-output-[msg-type].xml test data for remaining data types This was generated by running data from `udpsender_[msg-type].py` through the system locally and grabbing the value produced to `topic.Asn1DecoderOutput` Signed-off-by: Matt Cook * refactor: moved tests to Asn1DecodedDataRouterTest for test isolation and clarity Signed-off-by: Matt Cook * test: added test for BSMDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * test-refactor: extracted common methods for reusability of test code Signed-off-by: Matt Cook * test-refactor: extracted addTopics with try-catch-ignore to EmbeddedKafkaHolder for reusability Signed-off-by: Matt Cook * test: add missing SRM test case to GenericReceiverTest Signed-off-by: Matt Cook * style: rename rm to serviceManager in UdpServicesController to improve readability Signed-off-by: Matt Cook * test: added test for TIMDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * style: correct checkstyle violations in OdeBsmData Signed-off-by: Matt Cook * chore: added missing EqualsAndHashCode annotation to OdeBsmData This allows us to check object equality during testing instead of relying on JSON stringification Signed-off-by: Matt Cook * test-refactor: Refactored BSM data flow in Asn1DecodedDataRouterTest Changed the test code to execute the Asn1DecodedDataRouter consumption instead of the Spring Kafka consumption. This verifies the current functionality and will prevent any bug regressions or introductions during migration to Spring Kafka Signed-off-by: Matt Cook * test-refactor: pulled Asn1DecodedDataRouter setup into setup method Signed-off-by: Matt Cook * test-refactor: Refactored TIM data flow in Asn1DecodedDataRouterTest Changed the test code to execute the Asn1DecodedDataRouter consumption instead of the Spring Kafka consumption. This verifies the current functionality and will prevent any bug regressions or introductions during migration to Spring Kafka Signed-off-by: Matt Cook * test: added test for SPaTDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * test-refactor: improve test resource isolation in Asn1DecodedDataRouterTest Introduce unique Kafka topic names for isolation in tests and update consumers to handle specific topics. Signed-off-by: Matt Cook * test: added test for SSMDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * test: added test for SRMDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * test: added test for PSMDataFlow to Asn1DecodedDataRouterTest Signed-off-by: Matt Cook * test: added disabled test for MAPDataFlow to Asn1DecodedDataRouterTest Intent is to enable it once we migrate all code over to single listener Signed-off-by: Matt Cook * refactor: remove unnecessary Component annotation from Asn1DecodedDataListener Signed-off-by: Matt Cook * refactor: migrate all logic from Asn1DecodedDataRouter to Asn1DecodedDataListener Signed-off-by: Matt Cook * chore: replaced TimTransmogrifier usage with OdeTimDataCreatorHelper after merge of pojo rework updates Signed-off-by: Matt Cook * chore: added KafkaTemplate for producing OdeBsmData values Signed-off-by: Matt Cook * test: correct annotations in Asn1DecodedDataListener and Asn1DecodedDataRouterApprovalTest The annotation updates allow proper instantiation of beans and registration of KafkaListeners for the Asn1DecodedDataRouterApprovalTest Signed-off-by: Matt Cook * refactor: move and rename Asn1DecodedDataRouterApprovalTest.java to correct package Signed-off-by: Matt Cook * chore: correct expected-tim.json after move from TimTransmorgrifier Signed-off-by: Matt Cook * chore: deleted dangling merge artifact * test: replace Asn1DecodedDataRouter with Asn1DecodedDataListener in Asn1DecodedDataRouterTest * refactor: remove all references to Asn1DecodedDataRouter.java and delete class * refactor: rename listener method to accurately reflect functionality * refactor: update logging to be more human-readable and remove redundant log statements * chore: move Asn1DecodedDataRouterTest to correct package after migration to Asn1DecodedDataListener * chore: rename Asn1DecodedDataListener.java to Asn1DecodedDataRouter * fix: add back the Component annotation to Asn1DecodedDataRouter to correctly load listener * refactor: seal serializers and deserializers for improved structure. Removed unused J2735-specific classes and introduced sealed classes for `MessagingSerializer` and `MessagingDeserializer` to enforce subtyping rules. Marked `OdeBsmSerializer`, `OdeBsmDeserializer`, `OdeTimSerializer`, and `OdeTimDeserializer` as deprecated, promoting a cleaner and more maintainable design. * docs: update javadocs in serializer and deserializer classes for clarity. Added detailed class-level documentation to `MessagingSerializer` and `MessagingDeserializer` for better clarity on their functionality and usage. Enhanced readability of the code by aligning licensing comments and correcting minor inconsistencies. * test: enabled Asn1DecodedDataRouterTest map data flow test * test: stop listener container after each test In Asn1DecodedDataRouterTest, we need to stop the listener container after each test run to ensure the container can listen to embeddedKafka in a timely manner. Prior to this change, we would get `Asn1DecodedDataRouterTest.setup:118 » IllegalState Expected 1 but got 0 partitions` and intermittent test failures * test: listen to specific topics in KafkaProducerConfigTest * test: standardized Asn1DecodeMAPJSONTest to reduce variability in test runs * test: annotate KafkaProducerConfigTest with DirtiesContext to reduce risk of race conditions * test: standardize ReceiverTest annotations and setup * test: standardize Asn1DecodedDataRouterApprovalTest annotations and setup * test: refactored test to use unique keys for consumed matching Since this test suite produces to and consumes from the same topics in multiple tests, we needed a better way than `getSingleRecord` to perform test assertions. By using uuids as keys, we are able to reuse the same topics for multiple tests and select the correct records for test assertions without risk of tests conflicting with one another. * ci: remove `-X` flag from mvn command to reduce noise in output * test: introduce test configuration for KafkaProducerConfigTest This change helps simplify managing unique topic names for the disabledTopics set provided by OdeKafkaProperties. It is necessary to prevent data from other tests leaking onto the disabled topics and causing intermittent test failures in this suite * test: use correct deserializers for test consumer in Asn1DecodeMAPJSONTest * chore: add debug logging to addTopics in EmbeddedKafkaHolder * test: enable simple config of unique topic names in KafkaProducerConfigTest * ci: isolate ci.yml runs to pull_request and specific push events * Update jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java Co-authored-by: Drew Johnston <31270488+drewjj@users.noreply.github.com> * test: add failing test to ensure disabledTopic send does not interrupt program flow * refactor: replaced DisabledTopicsProducerInterceptor.java with InterceptingKafkaTemplate This allows us to prevent sending to disabled topics without throwing exceptions. It allows graceful blocking of sends to disabled topics where the previous exception-driven approach was interrupting normal code paths. * docs: correct wording in Javadocs * chore: swap disabled topic logging to debug level * test: update error messages to include correct file name --------- Signed-off-by: Matt Cook Co-authored-by: Drew Johnston <31270488+drewjj@users.noreply.github.com> --- .github/workflows/ci.yml | 10 +- .../us/dot/its/jpo/ode/model/OdeBsmData.java | 66 +- .../wrapper/serdes/J2735BsmDeserializer.java | 22 - .../wrapper/serdes/J2735BsmSerializer.java | 22 - .../wrapper/serdes/MessagingDeserializer.java | 63 +- .../wrapper/serdes/MessagingSerializer.java | 62 +- .../wrapper/serdes/OdeBsmDeserializer.java | 6 +- .../ode/wrapper/serdes/OdeBsmSerializer.java | 13 +- .../wrapper/serdes/OdeTimDeserializer.java | 22 - .../ode/wrapper/serdes/OdeTimSerializer.java | 13 +- .../jpo/ode/kafka/KafkaConsumerConfig.java | 56 - .../listeners/Asn1DecodedDataListener.java | 94 - .../listeners/Asn1DecodedDataRouter.java | 189 ++ .../producer/DisabledTopicException.java | 19 - .../DisabledTopicsProducerInterceptor.java | 66 - .../producer/InterceptingKafkaTemplate.java | 58 + .../kafka/producer/KafkaProducerConfig.java | 49 +- .../producer/LoggingProducerListener.java | 22 +- .../services/asn1/Asn1DecodedDataRouter.java | 206 -- .../asn1/AsnCodecRouterServiceController.java | 15 +- .../dot/its/jpo/ode/udp/bsm/BsmReceiver.java | 3 - .../jpo/ode/udp/generic/GenericReceiver.java | 3 - .../dot/its/jpo/ode/udp/map/MapReceiver.java | 30 +- .../dot/its/jpo/ode/udp/psm/PsmReceiver.java | 25 +- .../its/jpo/ode/udp/spat/SpatReceiver.java | 3 - .../dot/its/jpo/ode/udp/srm/SrmReceiver.java | 26 +- .../dot/its/jpo/ode/udp/ssm/SsmReceiver.java | 3 - .../dot/its/jpo/ode/udp/tim/TimReceiver.java | 26 +- .../jpo/ode/kafka/Asn1DecodeMAPJSONTest.java | 43 +- .../ode/kafka/KafkaProducerConfigTest.java | 131 +- .../Asn1DecodedDataRouterApprovalTest.java | 46 +- .../listeners/Asn1DecodedDataRouterTest.java | 417 ++++ .../asn1/Asn1DecodedDataRouterTest.java | 394 ---- .../test/utilities/EmbeddedKafkaHolder.java | 25 +- .../its/jpo/ode/udp/bsm/BsmReceiverTest.java | 13 +- .../ode/udp/generic/GenericReceiverTest.java | 43 +- .../its/jpo/ode/udp/map/MapReceiverTest.java | 9 +- .../its/jpo/ode/udp/psm/PsmReceiverTest.java | 2 + .../jpo/ode/udp/spat/SpatReceiverTest.java | 13 +- .../its/jpo/ode/udp/srm/SrmReceiverTest.java | 10 +- .../its/jpo/ode/udp/ssm/SsmReceiverTest.java | 12 +- .../its/jpo/ode/udp/tim/TimReceiverTest.java | 13 +- .../ode/services/asn1/decoder-output-bsm.xml | 235 +++ .../ode/services/asn1/decoder-output-map.xml | 1707 +++++++++++++++++ .../ode/services/asn1/decoder-output-psm.xml | 65 + .../ode/services/asn1/decoder-output-spat.xml | 146 ++ .../ode/services/asn1/decoder-output-srm.xml | 87 + .../ode/services/asn1/decoder-output-ssm.xml | 78 + .../ode/services/asn1/decoder-output-tim.xml | 214 +++ .../jpo/ode/services/asn1/expected-bsm.json | 83 + .../jpo/ode/services/asn1/expected-map.json | 1 + .../jpo/ode/services/asn1/expected-psm.json | 1 + .../jpo/ode/services/asn1/expected-spat.json | 1 + .../jpo/ode/services/asn1/expected-srm.json | 1 + .../jpo/ode/services/asn1/expected-ssm.json | 1 + .../services/asn1/expected-tim-specific.xml | 214 +++ .../jpo/ode/services/asn1/expected-tim.json | 1 + 57 files changed, 3904 insertions(+), 1294 deletions(-) delete mode 100644 jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmDeserializer.java delete mode 100644 jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmSerializer.java delete mode 100644 jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimDeserializer.java delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouter.java delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java create mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/InterceptingKafkaTemplate.java delete mode 100644 jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java rename jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/{services/asn1 => kafka/listeners}/Asn1DecodedDataRouterApprovalTest.java (72%) create mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterTest.java delete mode 100644 jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-bsm.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-map.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-psm.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-spat.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-srm.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-ssm.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-tim.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-bsm.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-map.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-psm.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-spat.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-srm.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-ssm.json create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim-specific.xml create mode 100644 jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b90998266..cbb2a541e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,12 @@ name: ci -on: [pull_request, push] +on: + pull_request: + push: + branches: + - "develop" + - "master" + - "release/*" jobs: docker: @@ -27,4 +33,4 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} run: | ls -la && pwd - mvn -e -X clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.projectKey=usdot.jpo.ode:jpo-ode -Dsonar.projectName=jpo-ode -Dsonar.organization=usdot-jpo-ode -Dsonar.host.url=https://sonarcloud.io -Dsonar.branch.name=$GITHUB_REF_NAME + mvn -e clean org.jacoco:jacoco-maven-plugin:prepare-agent package sonar:sonar -Dsonar.projectKey=usdot.jpo.ode:jpo-ode -Dsonar.projectName=jpo-ode -Dsonar.organization=usdot-jpo-ode -Dsonar.host.url=https://sonarcloud.io -Dsonar.branch.name=$GITHUB_REF_NAME diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeBsmData.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeBsmData.java index ad651c76d..397fd114a 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeBsmData.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/model/OdeBsmData.java @@ -1,45 +1,55 @@ /******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * Copyright 2018 572682. + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software + * of the License at

+ * + *

http://www.apache.org/licenses/LICENSE-2.0

+ * + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ + package us.dot.its.jpo.ode.model; -import com.fasterxml.jackson.annotation.JsonTypeInfo; -import static com.fasterxml.jackson.annotation.JsonTypeInfo.*; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import lombok.EqualsAndHashCode; + +/** + * Represents a specialized type of data in the Open Data Environment (ODE) system, specifically + * related to Basic Safety Messages (BSM). This class extends OdeData and provides BSM-specific + * metadata and payload handling. + */ +@EqualsAndHashCode(callSuper = false) public class OdeBsmData extends OdeData { - private static final long serialVersionUID = 4944935387116447760L; + private static final long serialVersionUID = 4944935387116447760L; - public OdeBsmData() { - super(); - } + public OdeBsmData() { + super(); + } - public OdeBsmData(OdeMsgMetadata metadata, OdeMsgPayload payload) { - super(metadata, payload); - } + public OdeBsmData(OdeMsgMetadata metadata, OdeMsgPayload payload) { + super(metadata, payload); + } - @Override - @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeBsmMetadata.class) - public void setMetadata(OdeMsgMetadata metadata) { - super.setMetadata(metadata); - } + @Override + @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeBsmMetadata.class) + public void setMetadata(OdeMsgMetadata metadata) { + super.setMetadata(metadata); + } - @Override - @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeBsmPayload.class) - public void setPayload(OdeMsgPayload payload) { - super.setPayload(payload); - } + @Override + @JsonTypeInfo(use = Id.CLASS, include = As.EXISTING_PROPERTY, defaultImpl = OdeBsmPayload.class) + public void setPayload(OdeMsgPayload payload) { + super.setPayload(payload); + } } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmDeserializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmDeserializer.java deleted file mode 100644 index 42ffafd04..000000000 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmDeserializer.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.wrapper.serdes; - -import us.dot.its.jpo.ode.plugin.j2735.J2735Bsm; - -public class J2735BsmDeserializer extends MessagingDeserializer { - -} diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmSerializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmSerializer.java deleted file mode 100644 index 176b6d36f..000000000 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/J2735BsmSerializer.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.wrapper.serdes; - -import us.dot.its.jpo.ode.plugin.j2735.J2735Bsm; - -public class J2735BsmSerializer extends MessagingSerializer { - -} diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingDeserializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingDeserializer.java index b9f16e558..4a79a5791 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingDeserializer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingDeserializer.java @@ -1,43 +1,44 @@ /******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * Copyright 2018 572682. + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software + * of the License at

+ * + *

http://www.apache.org/licenses/LICENSE-2.0

+ * + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ -package us.dot.its.jpo.ode.wrapper.serdes; -import java.util.Map; +package us.dot.its.jpo.ode.wrapper.serdes; import org.apache.kafka.common.serialization.Deserializer; - import us.dot.its.jpo.ode.util.SerializationUtils; -public class MessagingDeserializer implements Deserializer { - - SerializationUtils deserializer = new SerializationUtils(); - - @Override - public void configure(Map configs, boolean isKey) { - // nothing to do - } - - @Override - public T deserialize(String topic, byte[] data) { - return deserializer.deserialize(data); - } - - @Override - public void close() { - // nothing to do - } - +/** + * MessagingDeserializer is a generic base class implementing the Kafka Deserializer interface to + * provide deserialization of objects for use in Kafka messages. + * + *

This class uses a generic type parameter, allowing it to handle deserialization + * of various types. Internal deserialization is performed using an instance of the + * SerializationUtils class, which leverages Kryo for efficient object deserialization.

+ * + *

The class is declared as sealed, restricting which other classes can directly extend it. It + * will soon be marked as final to prevent incorrect usage through unnecessary subtyping

+ * + * @param the type of data to be deserialized + */ +public sealed class MessagingDeserializer implements Deserializer + permits OdeBsmDeserializer { + + SerializationUtils deserializer = new SerializationUtils<>(); + + @Override + public T deserialize(String topic, byte[] data) { + return deserializer.deserialize(data); + } } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingSerializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingSerializer.java index 335c96cc1..62e607739 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingSerializer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/MessagingSerializer.java @@ -1,42 +1,46 @@ /******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * Copyright 2018 572682. + * + *

Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software + * of the License at

+ * + *

http://www.apache.org/licenses/LICENSE-2.0

+ * + *

Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under - * the License. + * the License.

******************************************************************************/ -package us.dot.its.jpo.ode.wrapper.serdes; -import java.util.Map; +package us.dot.its.jpo.ode.wrapper.serdes; import org.apache.kafka.common.serialization.Serializer; - import us.dot.its.jpo.ode.util.SerializationUtils; -public class MessagingSerializer implements Serializer { - - SerializationUtils serializer = new SerializationUtils(); - - @Override - public void configure(Map configs, boolean isKey) { - } - - @Override - public byte[] serialize(String topic, T data) { - return serializer.serialize(data); - } - - @Override - public void close() { - // nothing to do - } +/** + * MessagingSerializer is a generic base class implementing the Kafka Serializer interface to + * provide serialization of objects for use in Kafka messages. + * + *

This class uses a generic type parameter, allowing it to handle serialization of various types. + * Internal serialization is performed using an instance of the SerializationUtils class, which + * leverages Kryo for efficient object serialization.

+ * + *

The class is declared as sealed, restricting which other classes can directly extend it. The + * class is declared as sealed, restricting which other classes can directly extend it. It will soon + * be marked as final to prevent incorrect usage through unnecessary subtyping

+ * + * @param the type of data to be serialized + */ +public sealed class MessagingSerializer implements Serializer + permits OdeBsmSerializer, OdeTimSerializer { + + SerializationUtils serializer = new SerializationUtils<>(); + + @Override + public byte[] serialize(String topic, T data) { + return serializer.serialize(data); + } } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmDeserializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmDeserializer.java index 0809ef8e9..24eaa6b61 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmDeserializer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmDeserializer.java @@ -17,6 +17,10 @@ import us.dot.its.jpo.ode.model.OdeBsmData; -public class OdeBsmDeserializer extends MessagingDeserializer { +/** + * @deprecated Use new MessagingDeserializer() instead where needed + */ +@Deprecated(forRemoval = true) +public non-sealed class OdeBsmDeserializer extends MessagingDeserializer { } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmSerializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmSerializer.java index 6fc317568..49a9aca22 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmSerializer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeBsmSerializer.java @@ -1,22 +1,27 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.wrapper.serdes; import us.dot.its.jpo.ode.model.OdeBsmData; -public class OdeBsmSerializer extends MessagingSerializer { +/** + * @deprecated Use new MessagingSerializer() instead where needed + */ +@Deprecated(forRemoval = true) +public non-sealed class OdeBsmSerializer extends MessagingSerializer { } diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimDeserializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimDeserializer.java deleted file mode 100644 index 9cdc0df3a..000000000 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimDeserializer.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.wrapper.serdes; - -import us.dot.its.jpo.ode.model.OdeTimData; - -public class OdeTimDeserializer extends MessagingDeserializer { - -} diff --git a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimSerializer.java b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimSerializer.java index 59e508f9e..d81f11620 100644 --- a/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimSerializer.java +++ b/jpo-ode-core/src/main/java/us/dot/its/jpo/ode/wrapper/serdes/OdeTimSerializer.java @@ -1,22 +1,27 @@ /******************************************************************************* * Copyright 2018 572682 - * + * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. ******************************************************************************/ + package us.dot.its.jpo.ode.wrapper.serdes; import us.dot.its.jpo.ode.model.OdeTimData; -public class OdeTimSerializer extends MessagingSerializer { +/** + * @deprecated Use new MessagingSerializer() instead where needed + */ +@Deprecated(forRemoval = true) +public non-sealed class OdeTimSerializer extends MessagingSerializer { } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java index 2b17bfb64..66d81bb9e 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/KafkaConsumerConfig.java @@ -4,7 +4,6 @@ import java.util.Map; import lombok.extern.slf4j.Slf4j; import org.apache.kafka.common.serialization.StringDeserializer; -import org.json.JSONObject; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -12,13 +11,8 @@ import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; -import org.springframework.kafka.listener.adapter.RecordFilterStrategy; import org.springframework.kafka.support.serializer.JsonDeserializer; -import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.model.OdeAsn1Data; import us.dot.its.jpo.ode.model.OdeMapData; -import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; -import us.dot.its.jpo.ode.util.XmlUtils; /** * Configures Kafka consumer settings and provides various consumer factories and listener container @@ -111,56 +105,6 @@ public ConcurrentKafkaListenerContainerFactory odeMapDataCon return factory; } - /** - * Creates a {@link ConcurrentKafkaListenerContainerFactory} for processing Kafka messages. This - * factory is configured to filter out certain messages based on a defined strategy. - * - * @return factory A listener factory that supports filtering out messages that don't match a - * specific pattern - * @deprecated This method is intended to be short-lived. It exists to allow consumption via the - * Asn1DecodedDataRouter & the Asn1DecodedDataListener while we are migrating from hand-rolled - * Kafka implementation to Spring's Kafka implementation - */ - @Bean - @Deprecated(forRemoval = true) - public ConcurrentKafkaListenerContainerFactory tempFilteringKafkaListenerContainerFactory() { - ConcurrentKafkaListenerContainerFactory factory = - new ConcurrentKafkaListenerContainerFactory<>(); - factory.setConsumerFactory(consumerFactory()); - factory.setRecordFilterStrategy(getFilterStrategySpringKafkaSupportedMessageTypesOnly()); - - return factory; - } - - /** - * While migrating to Spring Kafka the consumers provided from this factory will only consume (and - * ack) messages we support via the Spring Kafka implementation. All other messages will be - * handled by the Asn1DecodedDataRouter - * - * @return filter - */ - private static RecordFilterStrategy getFilterStrategySpringKafkaSupportedMessageTypesOnly() { - return consumerRecord -> { - try { - JSONObject consumed = XmlUtils.toJSONObject(consumerRecord.value()) - .getJSONObject(OdeAsn1Data.class.getSimpleName()); - - J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( - consumed.getJSONObject(AppContext.PAYLOAD_STRING).getJSONObject(AppContext.DATA_STRING) - .getJSONObject("MessageFrame").getInt("messageId")); - - // Filter out all messages EXCEPT for MAP messages - return !J2735DSRCmsgID.MAPMessage.equals(messageId); - } catch (XmlUtils.XmlUtilsException e) { - log.warn("Unable to parse JSON object", e); - return false; - } catch (Exception e) { - log.warn("Failed to detect message ID", e); - return false; - } - }; - } - private Map getKafkaConsumerProperties() { Map props = new HashMap<>(kafkaProperties.buildConsumerProperties()); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java deleted file mode 100644 index 49ad8d8c3..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataListener.java +++ /dev/null @@ -1,94 +0,0 @@ -package us.dot.its.jpo.ode.kafka.listeners; - -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.annotation.KafkaHandler; -import org.springframework.kafka.annotation.KafkaListener; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.messaging.handler.annotation.Headers; -import org.springframework.messaging.handler.annotation.Payload; -import org.springframework.stereotype.Component; -import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; -import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeLogMetadata; -import us.dot.its.jpo.ode.util.XmlUtils; - -/** - * The Asn1DecodedDataListener class is a component responsible for processing decoded ASN.1 data - * from Kafka topics. It listens to messages on a specified Kafka topic and handles the incoming - * data by processing and forwarding it to different topics based on specific criteria. - * - *

This listener is specifically designed to handle MAP data. Upon receiving a - * payload, it uses the {@link OdeMapDataCreatorHelper} to transform the payload and then determine - * the appropriate Kafka topic to forward the processed data. - * - *

The class utilizes Spring Kafka's annotation-driven listener configuration, - * allowing it to automatically consume messages from a configured Kafka topic. - */ -@Slf4j -@Component -@KafkaListener( - id = "Asn1DecodedDataListener", - topics = "${ode.kafka.topics.asn1.decoder-output}", - containerFactory = "tempFilteringKafkaListenerContainerFactory" -) -public class Asn1DecodedDataListener { - - private final String jsonMapTopic; - private final String pojoTxMapTopic; - private final KafkaTemplate kafkaTemplate; - - /** - * Constructs an instance of Asn1DecodedDataListener. - * - * @param kafkaTemplate the KafkaTemplate used for sending messages to Kafka topics. - * @param pojoTxMapTopic the name of the Kafka topic to which messages containing map transactions - * (mapTx) in POJO format are sent. - * @param jsonMapTopic the name of the Kafka topic where JSON-formatted messages are sent. - */ - public Asn1DecodedDataListener(KafkaTemplate kafkaTemplate, - @Value("${ode.kafka.topics.pojo.tx-map}") String pojoTxMapTopic, - @Value("${ode.kafka.topics.json.map}") String jsonMapTopic) { - this.kafkaTemplate = kafkaTemplate; - this.pojoTxMapTopic = pojoTxMapTopic; - this.jsonMapTopic = jsonMapTopic; - } - - /** - * Processes the given Kafka message payload by transforming it into ODE MAP data and publishing - * it to appropriate Kafka topics based on its record type. Specifically, it publishes all - * transformed MAP data to a JSON topic and conditionally to a transaction-map topic if the record - * type is `mapTx`. - * - * @param keys the headers of the Kafka message, typically containing metadata for the - * message. - * @param payload the payload of the Kafka message, expected to be a string representation of the - * data that needs to be transformed and processed. - */ - @KafkaHandler - public void listenToMAPs(@Headers Map keys, @Payload String payload) { - log.debug("Key: {} payload: {}", keys, payload); - try { - String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(payload).toString(); - - OdeLogMetadata.RecordType recordType = OdeLogMetadata.RecordType - .valueOf(XmlUtils.toJSONObject(payload) - .getJSONObject(OdeAsn1Data.class.getSimpleName()) - .getJSONObject(AppContext.METADATA_STRING) - .getString("recordType") - ); - if (recordType == OdeLogMetadata.RecordType.mapTx) { - log.debug("Publishing message with recordType: {} to {} ", recordType, - pojoTxMapTopic); - kafkaTemplate.send(pojoTxMapTopic, odeMapData); - } - - // Send all MAP data to OdeMapJson despite the record type - kafkaTemplate.send(jsonMapTopic, odeMapData); - } catch (Exception e) { - log.error(e.getMessage(), e); - } - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouter.java new file mode 100644 index 000000000..dc6dc0caa --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouter.java @@ -0,0 +1,189 @@ +package us.dot.its.jpo.ode.kafka.listeners; + +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.json.JSONObject; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.stereotype.Component; +import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeMapDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdePsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSpatDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSrmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeSsmDataCreatorHelper; +import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; +import us.dot.its.jpo.ode.context.AppContext; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; +import us.dot.its.jpo.ode.model.OdeAsn1Data; +import us.dot.its.jpo.ode.model.OdeBsmData; +import us.dot.its.jpo.ode.model.OdeLogMetadata; +import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; +import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; +import us.dot.its.jpo.ode.util.XmlUtils; +import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; + +/** + * The Asn1DecodedDataRouter class is a component responsible for processing decoded ASN.1 data from + * Kafka topics. It listens to messages on a specified Kafka topic and handles the incoming data by + * processing and forwarding it to different topics based on specific criteria. + * + *

This listener is specifically designed to handle decoded data produced by the asn1_codec. + * Upon receiving a payload, it transforms the payload and then determines the appropriate + * Kafka topic to forward the processed data.

+ * + *

The class utilizes Spring Kafka's annotation-driven listener configuration, + * allowing it to automatically consume messages from a configured Kafka topic.

+ */ +@Slf4j +@Component +public class Asn1DecodedDataRouter { + + private final PojoTopics pojoTopics; + private final JsonTopics jsonTopics; + private final KafkaTemplate kafkaTemplate; + private final KafkaTemplate bsmDataKafkaTemplate; + + /** + * Constructs an instance of Asn1DecodedDataRouter. + * + * @param kafkaTemplate the KafkaTemplate used for sending messages to Kafka topics. + */ + public Asn1DecodedDataRouter(KafkaTemplate kafkaTemplate, + KafkaTemplate bsmDataKafkaTemplate, + PojoTopics pojoTopics, + JsonTopics jsonTopics) { + this.kafkaTemplate = kafkaTemplate; + this.bsmDataKafkaTemplate = bsmDataKafkaTemplate; + this.pojoTopics = pojoTopics; + this.jsonTopics = jsonTopics; + } + + /** + * Processes the given Kafka message payload by transforming it into ODE data and publishing it to + * appropriate Kafka topics based on its record type. + */ + @KafkaListener( + id = "Asn1DecodedDataRouter", + topics = "${ode.kafka.topics.asn1.decoder-output}" + ) + public void listen(ConsumerRecord consumerRecord) throws XmlUtilsException { + log.debug("Key: {} payload: {}", consumerRecord.key(), consumerRecord.value()); + + JSONObject consumed = XmlUtils.toJSONObject(consumerRecord.value()) + .getJSONObject(OdeAsn1Data.class.getSimpleName()); + J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( + consumed.getJSONObject(AppContext.PAYLOAD_STRING) + .getJSONObject(AppContext.DATA_STRING) + .getJSONObject("MessageFrame") + .getInt("messageId") + ); + + OdeLogMetadata.RecordType recordType = OdeLogMetadata.RecordType + .valueOf(XmlUtils.toJSONObject(consumerRecord.value()) + .getJSONObject(OdeAsn1Data.class.getSimpleName()) + .getJSONObject(AppContext.METADATA_STRING) + .getString("recordType") + ); + + switch (messageId) { + case BasicSafetyMessage -> routeBSM(consumerRecord, recordType); + case TravelerInformation -> routeTIM(consumerRecord, recordType); + case SPATMessage -> routeSPAT(consumerRecord, recordType); + case MAPMessage -> routeMAP(consumerRecord, recordType); + case SSMMessage -> routeSSM(consumerRecord, recordType); + case SRMMessage -> routeSRM(consumerRecord, recordType); + case PersonalSafetyMessage -> routePSM(consumerRecord, recordType); + case null, default -> log.warn("Unknown message type: {}", messageId); + } + } + + private void routePSM(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumerRecord.value()).toString(); + if (recordType == RecordType.psmTx) { + kafkaTemplate.send(pojoTopics.getTxPsm(), consumerRecord.key(), odePsmData); + } + // Send all PSMs also to OdePsmJson + kafkaTemplate.send(jsonTopics.getPsm(), consumerRecord.key(), odePsmData); + } + + private void routeSRM(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumerRecord.value()).toString(); + if (recordType == RecordType.srmTx) { + kafkaTemplate.send(pojoTopics.getTxSrm(), consumerRecord.key(), odeSrmData); + } + // Send all SRMs also to OdeSrmJson + kafkaTemplate.send(jsonTopics.getSrm(), consumerRecord.key(), odeSrmData); + } + + private void routeSSM(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumerRecord.value()).toString(); + if (recordType == RecordType.ssmTx) { + kafkaTemplate.send(pojoTopics.getSsm(), consumerRecord.key(), odeSsmData); + } + // Send all SSMs also to OdeSsmJson + kafkaTemplate.send(jsonTopics.getSsm(), consumerRecord.key(), odeSsmData); + } + + private void routeSPAT(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtils.XmlUtilsException { + String odeSpatData = + OdeSpatDataCreatorHelper.createOdeSpatData(consumerRecord.value()).toString(); + switch (recordType) { + case dnMsg -> kafkaTemplate.send( + jsonTopics.getDnMessage(), consumerRecord.key(), odeSpatData); + case rxMsg -> kafkaTemplate.send(jsonTopics.getRxSpat(), consumerRecord.key(), odeSpatData); + case spatTx -> kafkaTemplate.send(pojoTopics.getTxSpat(), consumerRecord.key(), odeSpatData); + default -> log.trace("Consumed SPAT data with record type: {}", recordType); + } + // Send all SPATs also to OdeSpatJson + kafkaTemplate.send(jsonTopics.getSpat(), consumerRecord.key(), odeSpatData); + } + + + private void routeMAP(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtilsException { + String odeMapData = OdeMapDataCreatorHelper.createOdeMapData(consumerRecord.value()).toString(); + if (recordType == RecordType.mapTx) { + kafkaTemplate.send(pojoTopics.getTxMap(), odeMapData); + } + + // Send all MAP data to OdeMapJson despite the record type + kafkaTemplate.send(jsonTopics.getMap(), odeMapData); + } + + private void routeTIM(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtilsException { + String odeTimData = + OdeTimDataCreatorHelper.createOdeTimDataFromDecoded(consumerRecord.value()).toString(); + switch (recordType) { + case dnMsg -> kafkaTemplate.send(jsonTopics.getDnMessage(), consumerRecord.key(), odeTimData); + case rxMsg -> kafkaTemplate.send(jsonTopics.getRxTim(), consumerRecord.key(), odeTimData); + default -> log.trace("Consumed TIM data with record type: {}", recordType); + } + // Send all TIMs also to OdeTimJson + kafkaTemplate.send(jsonTopics.getTim(), consumerRecord.key(), odeTimData); + } + + private void routeBSM(ConsumerRecord consumerRecord, RecordType recordType) + throws XmlUtils.XmlUtilsException { + // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the "recordType" + OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumerRecord.value()); + switch (recordType) { + case bsmLogDuringEvent -> + bsmDataKafkaTemplate.send(pojoTopics.getBsmDuringEvent(), consumerRecord.key(), + odeBsmData); + case rxMsg -> + bsmDataKafkaTemplate.send(pojoTopics.getRxBsm(), consumerRecord.key(), odeBsmData); + case bsmTx -> + bsmDataKafkaTemplate.send(pojoTopics.getTxBsm(), consumerRecord.key(), odeBsmData); + default -> log.trace("Consumed BSM data with record type: {}", recordType); + } + // Send all BSMs also to OdeBsmPojo + bsmDataKafkaTemplate.send(pojoTopics.getBsm(), consumerRecord.key(), odeBsmData); + } +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java deleted file mode 100644 index 894d7f299..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicException.java +++ /dev/null @@ -1,19 +0,0 @@ -package us.dot.its.jpo.ode.kafka.producer; - -/** - * DisabledTopicException is a custom exception that extends RuntimeException. - * It is thrown to indicate that a particular Kafka topic is disabled and cannot - * be used for publishing messages. This exception is typically used in Kafka - * producer configurations or interceptors to prevent message delivery to topics - * that are not allowed or are inactive. - * - *

The exception takes the name of the disabled topic as a parameter and constructs - * an informative error message indicating that the topic is disabled. - * - */ -public final class DisabledTopicException extends RuntimeException { - - public DisabledTopicException(String topic) { - super(String.format("Blocked attempt to send data to disabled topic %s", topic)); - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java deleted file mode 100644 index b5067a440..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/DisabledTopicsProducerInterceptor.java +++ /dev/null @@ -1,66 +0,0 @@ -package us.dot.its.jpo.ode.kafka.producer; - -import java.util.Map; -import java.util.Set; -import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.producer.ProducerInterceptor; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.apache.kafka.clients.producer.RecordMetadata; - -/** - * Through a set of disabled topics provided during initialization, this interceptor enforces that - * messages are not sent to these topics. If an attempt is made to send a message to a disabled - * topic, the interceptor throws a DisabledTopicException, effectively preventing the message from - * being dispatched. - * - *

The class also provides default logging behavior upon message acknowledgement and - * during interceptor closure. - * - * @param the type of the key for Kafka producer records - * @param the type of the value for Kafka producer records - */ -@Slf4j -public class DisabledTopicsProducerInterceptor - implements ProducerInterceptor { - - private final Set disabledTopics; - - /** - * Constructs a DisabledTopicsProducerInterceptor with a specified set of disabled topics. - * This set determines which topics are restricted from message dispatching. - * - * @param disabledTopics a set of topic names that are marked as disabled. Messages sent to these - * topics will result in a DisabledTopicException being thrown, ensuring - * they are not dispatched. - */ - protected DisabledTopicsProducerInterceptor(Set disabledTopics) { - this.disabledTopics = disabledTopics; - } - - @Override - public ProducerRecord onSend(ProducerRecord producerRecord) { - if (disabledTopics.contains(producerRecord.topic())) { - throw new DisabledTopicException(producerRecord.topic()); - } - return producerRecord; - } - - @Override - public void onAcknowledgement(RecordMetadata recordMetadata, Exception e) { - log.debug("Acknowledged message with offset {} on partition {}", recordMetadata.offset(), - recordMetadata.partition()); - if (e != null) { - log.error("Error acknowledging message", e); - } - } - - @Override - public void close() { - log.debug("Closing ProducerInterceptor"); - } - - @Override - public void configure(Map configs) { - // Default implementation - } -} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/InterceptingKafkaTemplate.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/InterceptingKafkaTemplate.java new file mode 100644 index 000000000..459f1b73a --- /dev/null +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/InterceptingKafkaTemplate.java @@ -0,0 +1,58 @@ +package us.dot.its.jpo.ode.kafka.producer; + +import io.micrometer.observation.Observation; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.apache.kafka.clients.producer.RecordMetadata; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.core.ProducerFactory; +import org.springframework.kafka.support.SendResult; +import org.springframework.lang.NonNull; + +/** + * InterceptingKafkaTemplate is an extension of the KafkaTemplate class designed to introduce a + * mechanism for selectively preventing messages from being sent to certain Kafka topics. This + * functionality is implemented via a set of "disabledTopics", which contains topic names that + * should be blocked from receiving messages. + * + * @param the type of message key + * @param the type of message value + */ +@Slf4j +public class InterceptingKafkaTemplate extends KafkaTemplate { + + private final Set disabledTopics; + + /** + * Create an instance using the supplied producer factory and autoFlush false. + * + * @param producerFactory the producer factory. + */ + public InterceptingKafkaTemplate( + ProducerFactory producerFactory, Set disabledTopics) { + super(producerFactory); + this.disabledTopics = disabledTopics; + } + + /** + * Send the producer record if the producerRecord's topic is not contained in the disabledTopics. + * + * @param producerRecord the producer record. + * @param observation the observation. + * @return a Future for the {@link RecordMetadata RecordMetadata}. + */ + @Override + protected CompletableFuture> doSend( + final ProducerRecord producerRecord, + @NonNull Observation observation) { + if (disabledTopics.contains(producerRecord.topic())) { + log.debug("Blocked attempt to send data to disabled topic {}", producerRecord.topic()); + return new CompletableFuture<>(); + } + + return super.doSend(producerRecord, observation); + } + +} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java index 8590efe2f..21294c2f5 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/KafkaProducerConfig.java @@ -11,7 +11,9 @@ import org.springframework.kafka.core.ProducerFactory; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.XMLOdeObjectSerializer; +import us.dot.its.jpo.ode.model.OdeBsmData; import us.dot.its.jpo.ode.model.OdeObject; +import us.dot.its.jpo.ode.wrapper.serdes.MessagingSerializer; /** * KafkaProducerConfig is a configuration class for setting up Kafka producers with Spring Boot. @@ -75,10 +77,9 @@ public ProducerFactory producerFactory() { @Bean public KafkaTemplate kafkaTemplate( ProducerFactory producerFactory) { - var template = new KafkaTemplate<>(producerFactory); + var template = new InterceptingKafkaTemplate<>(producerFactory, + this.odeKafkaProperties.getDisabledTopics()); - template.setProducerInterceptor( - new DisabledTopicsProducerInterceptor<>(this.odeKafkaProperties.getDisabledTopics())); template.setProducerListener(new LoggingProducerListener<>()); return template; @@ -113,15 +114,49 @@ public ProducerFactory odeDataProducerFactory() { public KafkaTemplate odeDataKafkaTemplate( ProducerFactory producerFactory ) { - var template = new KafkaTemplate<>(producerFactory); - template.setProducerInterceptor(new DisabledTopicsProducerInterceptor<>( - this.odeKafkaProperties.getDisabledTopics() - )); + var template = new InterceptingKafkaTemplate<>(producerFactory, + this.odeKafkaProperties.getDisabledTopics()); template.setProducerListener(new LoggingProducerListener<>()); return template; } + /** + * Creates a Kafka ProducerFactory configured for producing messages with String keys and + * OdeBsmData values. This factory utilizes the provided producer properties, along with specific + * serializers for the key and value types. + * + * @return a ProducerFactory instance configured for handling String keys and OdeBsmData values + * with the necessary serialization settings and application-specific properties. + */ + @Bean + public ProducerFactory odeBsmProducerFactory() { + return new DefaultKafkaProducerFactory<>(buildProducerProperties(), + new StringSerializer(), new MessagingSerializer<>()); + } + + /** + * Creates a KafkaTemplate specifically configured for handling messages with String keys and + * OdeBsmData values. This KafkaTemplate incorporates a {@link InterceptingKafkaTemplate} to block + * messages being sent to disabled topics and a LoggingProducerListener for logging producer + * activity. + * + * @param producerFactory the ProducerFactory used to create Kafka producers for sending messages + * with String keys and OdeBsmData values. Configures the necessary + * serializers and properties. + * @return a KafkaTemplate instance configured for publishing messages to Kafka topics with String + * keys and OdeBsmData values, ensuring proper handling of disabled topics and logging. + */ + @Bean + public KafkaTemplate odeBsmKafkaTemplate( + ProducerFactory producerFactory + ) { + var template = new InterceptingKafkaTemplate<>(producerFactory, + this.odeKafkaProperties.getDisabledTopics()); + template.setProducerListener(new LoggingProducerListener<>()); + return template; + } + private Map buildProducerProperties() { var producerProps = kafkaProperties.buildProducerProperties(); if ("CONFLUENT".equals(this.odeKafkaProperties.getKafkaType())) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java index b74ad3211..2428915fb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/kafka/producer/LoggingProducerListener.java @@ -7,11 +7,11 @@ import org.springframework.lang.Nullable; /** - * The LoggingProducerListener is a Kafka ProducerListener implementation that - * handles logging for Kafka producer events. + * The LoggingProducerListener is a Kafka ProducerListener implementation that handles logging for + * Kafka producer events. * - *

This class uses Slf4j for logging and should be added to Kafka producer - * configurations where logging of producer activity is required. + *

This class uses Slf4j for logging and should be added to Kafka producer + * configurations where logging of producer activity is required.

* * @param the type of the key for Kafka producer records * @param the type of the value for Kafka producer records @@ -22,8 +22,8 @@ public final class LoggingProducerListener @Override public void onSuccess(ProducerRecord producerRecord, RecordMetadata recordMetadata) { - log.debug("Successfully produced key {} and value {} to topic {}", producerRecord.key(), - producerRecord.value(), producerRecord.topic()); + log.debug("Successfully produced to topic {} with key {} and value {} ", producerRecord.topic(), + producerRecord.key(), producerRecord.value()); } @Override @@ -31,13 +31,7 @@ public void onError( ProducerRecord producerRecord, @Nullable RecordMetadata recordMetadata, Exception exception) { - if (exception instanceof DisabledTopicException) { - log.warn( - "Disabled topic exception encountered while producing key {} and value {} to topic {}", - producerRecord.key(), producerRecord.value(), producerRecord.topic()); - } else { - log.error("Failed to produce key {} and value {} to topic {}", producerRecord.key(), - producerRecord.value(), producerRecord.topic(), exception); - } + log.error("Failed to produce to topic {} with key {} and value {} ", producerRecord.topic(), + producerRecord.key(), producerRecord.value(), exception); } } diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java deleted file mode 100644 index 3a1e9619b..000000000 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouter.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - *

Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - *

http://www.apache.org/licenses/LICENSE-2.0 - * - *

Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ - -package us.dot.its.jpo.ode.services.asn1; - -import lombok.extern.slf4j.Slf4j; -import org.json.JSONObject; -import us.dot.its.jpo.ode.coder.OdeBsmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdePsmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSpatDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSrmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeSsmDataCreatorHelper; -import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; -import us.dot.its.jpo.ode.context.AppContext; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.topics.PojoTopics; -import us.dot.its.jpo.ode.model.OdeAsn1Data; -import us.dot.its.jpo.ode.model.OdeBsmData; -import us.dot.its.jpo.ode.model.OdeLogMetadata.RecordType; -import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; -import us.dot.its.jpo.ode.util.XmlUtils; -import us.dot.its.jpo.ode.wrapper.AbstractSubscriberProcessor; -import us.dot.its.jpo.ode.wrapper.MessageProducer; -import us.dot.its.jpo.ode.wrapper.serdes.OdeBsmSerializer; - -/** - * The Asn1DecodedDataRouter is responsible for routing all decoded messages - * from the topic.Asn1DecoderOutput Kafka topic to become deserialized POJOs - * and be written back to Kafka. - **/ -@Slf4j -public class Asn1DecodedDataRouter extends AbstractSubscriberProcessor { - - private final PojoTopics pojoTopics; - private final JsonTopics jsonTopics; - private final MessageProducer bsmProducer; - private final MessageProducer timProducer; - private final MessageProducer spatProducer; - private final MessageProducer ssmProducer; - private final MessageProducer srmProducer; - private final MessageProducer psmProducer; - - /** - * Creates a copy of Asn1DecodedDataRouter to actively consume from Kafka and write the - * deserialized output to the specified POJO and JSON topics. - * - * @param odeKafkaProperties The Kafka properties used to consume and produce to Kafka - * @param pojoTopics The specified POJO topics to write the deserialized POJO output to - * @param jsonTopics The specified JSON topics to write the deserialized JSON output to - **/ - public Asn1DecodedDataRouter(OdeKafkaProperties odeKafkaProperties, PojoTopics pojoTopics, - JsonTopics jsonTopics) { - super(); - - this.pojoTopics = pojoTopics; - this.jsonTopics = jsonTopics; - this.bsmProducer = new MessageProducer<>( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - null, - OdeBsmSerializer.class.getName(), - odeKafkaProperties.getDisabledTopics()); - this.timProducer = MessageProducer.defaultStringMessageProducer( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.spatProducer = MessageProducer.defaultStringMessageProducer( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.ssmProducer = MessageProducer.defaultStringMessageProducer( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.srmProducer = MessageProducer.defaultStringMessageProducer( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - this.psmProducer = MessageProducer.defaultStringMessageProducer( - odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(), - odeKafkaProperties.getDisabledTopics()); - } - - @Override - public Object process(String consumedData) { - try { - JSONObject consumed = XmlUtils.toJSONObject(consumedData).getJSONObject( - OdeAsn1Data.class.getSimpleName()); - J2735DSRCmsgID messageId = J2735DSRCmsgID.valueOf( - consumed.getJSONObject(AppContext.PAYLOAD_STRING) - .getJSONObject(AppContext.DATA_STRING) - .getJSONObject("MessageFrame") - .getInt("messageId")); - - RecordType recordType = RecordType - .valueOf(consumed.getJSONObject(AppContext.METADATA_STRING).getString("recordType")); - - switch (messageId) { - case BasicSafetyMessage -> routeBSM(consumedData, recordType); - case TravelerInformation -> routeTIM(consumedData, recordType); - case SPATMessage -> routeSPAT(consumedData, recordType); - case MAPMessage -> log.debug("MAP data processing no longer supported in this router."); - case SSMMessage -> routeSSM(consumedData, recordType); - case SRMMessage -> routeSRM(consumedData, recordType); - case PersonalSafetyMessage -> routePSM(consumedData, recordType); - case null, default -> log.warn("Unknown message type: {}", messageId); - } - } catch (Exception e) { - log.error("Failed to route received data: {}", consumedData, e); - } - return null; - } - - private void routePSM(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - String odePsmData = OdePsmDataCreatorHelper.createOdePsmData(consumedData).toString(); - if (recordType == RecordType.psmTx) { - psmProducer.send(pojoTopics.getTxPsm(), getRecord().key(), odePsmData); - } - // Send all PSMs also to OdePsmJson - psmProducer.send(jsonTopics.getPsm(), getRecord().key(), odePsmData); - log.debug("Submitted to PSM Pojo topic {}", jsonTopics.getPsm()); - } - - private void routeSRM(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - String odeSrmData = OdeSrmDataCreatorHelper.createOdeSrmData(consumedData).toString(); - if (recordType == RecordType.srmTx) { - srmProducer.send(pojoTopics.getTxSrm(), getRecord().key(), odeSrmData); - } - // Send all SRMs also to OdeSrmJson - srmProducer.send(jsonTopics.getSrm(), getRecord().key(), odeSrmData); - log.debug("Submitted to SRM Pojo topic {}", jsonTopics.getSrm()); - } - - private void routeSSM(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - String odeSsmData = OdeSsmDataCreatorHelper.createOdeSsmData(consumedData).toString(); - if (recordType == RecordType.ssmTx) { - ssmProducer.send(pojoTopics.getSsm(), getRecord().key(), odeSsmData); - } - // Send all SSMs also to OdeSsmJson - ssmProducer.send(jsonTopics.getSsm(), getRecord().key(), odeSsmData); - log.debug("Submitted to SSM Pojo topic {}", jsonTopics.getSsm()); - } - - private void routeSPAT(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - String odeSpatData = OdeSpatDataCreatorHelper.createOdeSpatData(consumedData).toString(); - switch (recordType) { - case dnMsg -> spatProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeSpatData); - case rxMsg -> spatProducer.send(jsonTopics.getRxSpat(), getRecord().key(), odeSpatData); - case spatTx -> spatProducer.send(pojoTopics.getTxSpat(), getRecord().key(), odeSpatData); - default -> log.trace("Consumed SPAT data with record type: {}", recordType); - } - // Send all SPATs also to OdeSpatJson - spatProducer.send(jsonTopics.getSpat(), getRecord().key(), odeSpatData); - log.debug("Submitted to SPAT Pojo topic {}", jsonTopics.getSpat()); - } - - private void routeTIM(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - String odeTimData = OdeTimDataCreatorHelper.createOdeTimDataFromDecoded( - consumedData).toString(); - switch (recordType) { - case dnMsg -> timProducer.send(jsonTopics.getDnMessage(), getRecord().key(), odeTimData); - case rxMsg -> timProducer.send(jsonTopics.getRxTim(), getRecord().key(), odeTimData); - default -> log.trace("Consumed TIM data with record type: {}", recordType); - } - // Send all TIMs also to OdeTimJson - timProducer.send(jsonTopics.getTim(), getRecord().key(), odeTimData); - log.debug("Submitted to TIM Pojo topic: {}", jsonTopics.getTim()); - } - - private void routeBSM(String consumedData, RecordType recordType) - throws XmlUtils.XmlUtilsException { - // ODE-518/ODE-604 Demultiplex the messages to appropriate topics based on the - // "recordType" - OdeBsmData odeBsmData = OdeBsmDataCreatorHelper.createOdeBsmData(consumedData); - switch (recordType) { - case bsmLogDuringEvent -> bsmProducer.send(pojoTopics.getBsmDuringEvent(), - getRecord().key(), odeBsmData); - case rxMsg -> bsmProducer.send(pojoTopics.getRxBsm(), getRecord().key(), odeBsmData); - case bsmTx -> bsmProducer.send(pojoTopics.getTxBsm(), getRecord().key(), odeBsmData); - default -> log.trace("Consumed BSM data with record type: {}", recordType); - } - // Send all BSMs also to OdeBsmPojo - bsmProducer.send(pojoTopics.getBsm(), getRecord().key(), odeBsmData); - log.debug("Submitted to BSM Pojo topic {}", pojoTopics.getBsm()); - } -} diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java index ab1a84898..7734b2115 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/services/asn1/AsnCodecRouterServiceController.java @@ -18,10 +18,9 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.kafka.topics.SDXDepositorTopics; import us.dot.its.jpo.ode.rsu.RsuProperties; import us.dot.its.jpo.ode.security.SecurityServicesProperties; @@ -37,7 +36,6 @@ public class AsnCodecRouterServiceController { @Autowired public AsnCodecRouterServiceController(OdeKafkaProperties odeKafkaProperties, JsonTopics jsonTopics, - PojoTopics pojoTopics, Asn1CoderTopics asn1CoderTopics, SDXDepositorTopics sdxDepositorTopics, RsuProperties rsuProperties, @@ -46,17 +44,6 @@ public AsnCodecRouterServiceController(OdeKafkaProperties odeKafkaProperties, log.info("Starting {}", this.getClass().getSimpleName()); - // asn1_codec Decoder Routing - log.info("Routing DECODED data received ASN.1 Decoder"); - - Asn1DecodedDataRouter decoderRouter = new Asn1DecodedDataRouter(odeKafkaProperties, pojoTopics, jsonTopics); - - MessageConsumer asn1DecoderConsumer = MessageConsumer.defaultStringMessageConsumer( - odeKafkaProperties.getBrokers(), this.getClass().getSimpleName(), decoderRouter); - - asn1DecoderConsumer.setName("Asn1DecoderConsumer"); - decoderRouter.start(asn1DecoderConsumer, asn1CoderTopics.getDecoderOutput()); - // asn1_codec Encoder Routing log.info("Routing ENCODED data received ASN.1 Encoder"); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java index 92ba00d9e..507cd5d57 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiver.java @@ -3,7 +3,6 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; @@ -65,8 +64,6 @@ public void run() { }); } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java index 1e53b192f..f2810860d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/generic/GenericReceiver.java @@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.tomcat.util.buf.HexUtils; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; @@ -73,8 +72,6 @@ public void run() { String messageType = UperUtil.determineHexPacketType(payloadHexString); routeMessageByMessageType(messageType, packet); - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (UnsupportedMessageTypeException e) { log.error("Unsupported Message Type", e); } catch (InvalidPayloadException e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java index ce828d60b..77d2f26b6 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/map/MapReceiver.java @@ -3,21 +3,19 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; /** - * The MapReceiver class is responsible for receiving UDP packets, decoding - * them, and publishing the decoded JSON map to a specified Kafka topic. - * It extends the {@link AbstractUdpReceiverPublisher} class to leverage UDP - * receiving capabilities. + * The MapReceiver class is responsible for receiving UDP packets, decoding them, and publishing the + * decoded JSON map to a specified Kafka topic. It extends the {@link AbstractUdpReceiverPublisher} + * class to leverage UDP receiving capabilities. * *

MapReceiver listens on a specified port for incoming UDP packets encapsulating - * map data, and decodes these packets. Upon successful decoding, the map data is published - * to a Kafka topic using KafkaTemplate. + * map data, and decodes these packets. Upon successful decoding, the map data is published to a + * Kafka topic using KafkaTemplate. */ @Slf4j public class MapReceiver extends AbstractUdpReceiverPublisher { @@ -26,16 +24,14 @@ public class MapReceiver extends AbstractUdpReceiverPublisher { private final String publishTopic; /** - * Constructs a new MapReceiver instance to receive UDP packets, decode them, - * and publish the decoded map data to a specified Kafka topic. + * Constructs a new MapReceiver instance to receive UDP packets, decode them, and publish the + * decoded map data to a specified Kafka topic. * - * @param receiverProperties The properties that define the UDP receiver - * configuration, including the port on which to - * listen and the buffer size for incoming packets. - * @param kafkaTemplate The KafkaTemplate instance used to send messages - * to the Kafka topic. - * @param publishTopic The topic to which decoded map data should be - * published. + * @param receiverProperties The properties that define the UDP receiver configuration, including + * the port on which to listen and the buffer size for incoming + * packets. + * @param kafkaTemplate The KafkaTemplate instance used to send messages to the Kafka topic. + * @param publishTopic The topic to which decoded map data should be published. */ public MapReceiver(UDPReceiverProperties.ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { @@ -62,8 +58,6 @@ public void run() { } else { log.debug("Ignoring empty packet from {}", packet.getSocketAddress()); } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java index 7915ceb07..a7619230b 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/psm/PsmReceiver.java @@ -3,20 +3,19 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; /** - * The PsmReceiver class extends AbstractUdpReceiverPublisher and is responsible for receiving - * UDP packets containing PSM (Position & Status Message) data, decoding them from their - * hex representation to JSON format, and then publishing the JSON data to a Kafka topic. + * The PsmReceiver class extends AbstractUdpReceiverPublisher and is responsible for receiving UDP + * packets containing PSM (Position & Status Message) data, decoding them from their hex + * representation to JSON format, and then publishing the JSON data to a Kafka topic. * *

- * The class utilizes a KafkaTemplate for publishing messages and a configurable topic - * name where the decoded PSM JSON messages are sent. + * The class utilizes a KafkaTemplate for publishing messages and a configurable topic name where + * the decoded PSM JSON messages are sent. */ @Slf4j public class PsmReceiver extends AbstractUdpReceiverPublisher { @@ -25,15 +24,15 @@ public class PsmReceiver extends AbstractUdpReceiverPublisher { private final String publishTopic; /** - * Constructs a PsmReceiver object that listens for UDP packets containing - * Position & Status Message (PSM) data, decodes them, and publishes the decoded - * JSON data to a specified Kafka topic. + * Constructs a PsmReceiver object that listens for UDP packets containing Position & Status + * Message (PSM) data, decodes them, and publishes the decoded JSON data to a specified Kafka + * topic. * * @param receiverProperties The properties containing configuration details such as the port to * listen on and buffer size. - * @param kafkaTemplate The KafkaTemplate used to publish messages to a Kafka topic. - * @param publishTopic The name of the Kafka topic to which decoded PSM JSON messages - * should be published. + * @param kafkaTemplate The KafkaTemplate used to publish messages to a Kafka topic. + * @param publishTopic The name of the Kafka topic to which decoded PSM JSON messages should + * be published. */ public PsmReceiver(ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { @@ -59,8 +58,6 @@ public void run() { psmPublisher.send(publishTopic, psmJson); } } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java index d5d6f0f65..e6781a72a 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/spat/SpatReceiver.java @@ -3,7 +3,6 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; @@ -58,8 +57,6 @@ public void run() { spatPublisher.send(publishTopic, spatJson); } } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java index 5fe8f7257..855f6ca6d 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/srm/SrmReceiver.java @@ -3,7 +3,6 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; @@ -14,12 +13,12 @@ * data, decoding them, and publishing the decoded messages to a specified Kafka topic. * *

- * This class extends the AbstractUdpReceiverPublisher and overrides its run method to implement - * the logic for receiving packets, processing them, and sending the result to Kafka. + * This class extends the AbstractUdpReceiverPublisher and overrides its run method to implement the + * logic for receiving packets, processing them, and sending the result to Kafka. * *

- * It utilizes a KafkaTemplate for sending messages to Kafka and uses a DatagramSocket to listen - * for incoming UDP packets on a specified port. + * It utilizes a KafkaTemplate for sending messages to Kafka and uses a DatagramSocket to listen for + * incoming UDP packets on a specified port. */ @Slf4j public class SrmReceiver extends AbstractUdpReceiverPublisher { @@ -28,13 +27,14 @@ public class SrmReceiver extends AbstractUdpReceiverPublisher { private final String publishTopic; /** - * Constructs an instance of SrmReceiver which is responsible for receiving UDP packets - * carrying SRM data, decoding them, and publishing the results to a Kafka topic. + * Constructs an instance of SrmReceiver which is responsible for receiving UDP packets carrying + * SRM data, decoding them, and publishing the results to a Kafka topic. * - * @param receiverProperties the properties for configuring the UDP receiver, including port - * and buffer size. - * @param kafkaTemplate the KafkaTemplate to be used for publishing decoded messages to Kafka. - * @param publishTopic the Kafka topic to which the decoded SRM messages will be published. + * @param receiverProperties the properties for configuring the UDP receiver, including port and + * buffer size. + * @param kafkaTemplate the KafkaTemplate to be used for publishing decoded messages to + * Kafka. + * @param publishTopic the Kafka topic to which the decoded SRM messages will be published. */ public SrmReceiver(ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { @@ -60,9 +60,7 @@ public void run() { srmPublisher.send(publishTopic, srmJson); } } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); - } catch (InvalidPayloadException e) { + } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { log.error("Error receiving packet", e); diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java index e6abdd536..9175eefcb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiver.java @@ -3,7 +3,6 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; @@ -52,8 +51,6 @@ public void run() { ssmPublisher.send(publishTopic, ssmJson); } } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java index 701e9c5b0..26dcddebb 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/udp/tim/TimReceiver.java @@ -3,17 +3,15 @@ import java.net.DatagramPacket; import lombok.extern.slf4j.Slf4j; import org.springframework.kafka.core.KafkaTemplate; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; import us.dot.its.jpo.ode.udp.AbstractUdpReceiverPublisher; import us.dot.its.jpo.ode.udp.InvalidPayloadException; import us.dot.its.jpo.ode.udp.UdpHexDecoder; import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties.ReceiverProperties; /** - * The TimReceiver class extends the AbstractUdpReceiverPublisher and is responsible - * for receiving UDP packets containing TIM (Traveler Information Message) data. - * Upon receiving a packet, it decodes the TIM data and forwards it to a specified - * Kafka topic using a KafkaTemplate. + * The TimReceiver class extends the AbstractUdpReceiverPublisher and is responsible for receiving + * UDP packets containing TIM (Traveler Information Message) data. Upon receiving a packet, it + * decodes the TIM data and forwards it to a specified Kafka topic using a KafkaTemplate. */ @Slf4j public class TimReceiver extends AbstractUdpReceiverPublisher { @@ -22,15 +20,15 @@ public class TimReceiver extends AbstractUdpReceiverPublisher { private final String publishTopic; /** - * Constructs a TimReceiver for receiving UDP packets and forwarding TIM - * (Traveler Information Message) data to a Kafka topic. + * Constructs a TimReceiver for receiving UDP packets and forwarding TIM (Traveler Information + * Message) data to a Kafka topic. * - * @param receiverProperties contains configuration properties such as - * receiver port and buffer size needed for establishing the UDP receiver. - * @param kafkaTemplate the KafkaTemplate used for sending the TIM data to the specified - * Kafka topic after decoding. - * @param publishTopic the name of the Kafka topic to which the decoded TIM data should - * be published. + * @param receiverProperties contains configuration properties such as receiver port and buffer + * size needed for establishing the UDP receiver. + * @param kafkaTemplate the KafkaTemplate used for sending the TIM data to the specified + * Kafka topic after decoding. + * @param publishTopic the name of the Kafka topic to which the decoded TIM data should be + * published. */ public TimReceiver(ReceiverProperties receiverProperties, KafkaTemplate kafkaTemplate, String publishTopic) { @@ -59,8 +57,6 @@ public void run() { timPublisher.send(publishTopic, timJson); } } - } catch (DisabledTopicException e) { - log.warn(e.getMessage()); } catch (InvalidPayloadException e) { log.error("Error decoding packet", e); } catch (Exception e) { diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java index 40ed1b4c8..fef3afcbe 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/Asn1DecodeMAPJSONTest.java @@ -7,19 +7,16 @@ import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.awaitility.Awaitility; +import org.apache.kafka.common.serialization.StringDeserializer; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; -import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; @@ -55,45 +52,33 @@ class Asn1DecodeMAPJSONTest { @Value(value = "${ode.kafka.topics.asn1.decoder-input}") private String asn1DecoderInput; + @Autowired + KafkaTemplate producer; private static final EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); @Test void testProcess_ApprovalTest() throws IOException { - Awaitility.setDefaultTimeout(250, java.util.concurrent.TimeUnit.MILLISECONDS); - try { - EmbeddedKafkaHolder.getEmbeddedKafka().addTopics( - new NewTopic(rawEncodedMapJson, 1, (short) 1), - new NewTopic(asn1DecoderInput, 1, (short) 1) - ); - } catch (Exception e) { - log.warn("New topics not created: {}", e.getMessage()); - } + String[] topics = {rawEncodedMapJson, asn1DecoderInput}; + EmbeddedKafkaHolder.addTopics(topics); String path = "src/test/resources/us.dot.its.jpo.ode.udp.map/JSONEncodedMAP_to_Asn1DecoderInput_Validation.json"; List approvalTestCases = deserializeTestCases(path); - Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); - DefaultKafkaProducerFactory producerFactory = - new DefaultKafkaProducerFactory<>(producerProps); - Producer producer = producerFactory.createProducer(); - Map consumerProps = - KafkaTestUtils.consumerProps(this.getClass().getSimpleName(), "false", embeddedKafka); - DefaultKafkaConsumerFactory cf = - new DefaultKafkaConsumerFactory<>(consumerProps); - Consumer testConsumer = cf.createConsumer(); + KafkaTestUtils.consumerProps("Asn1DecodeMapJSONTestConsumer", "false", embeddedKafka); + var cf = + new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + Consumer testConsumer = cf.createConsumer(); embeddedKafka.consumeFromAnEmbeddedTopic(testConsumer, asn1DecoderInput); for (ApprovalTestCase approvalTestCase : approvalTestCases) { // produce the test case input to the topic for consumption by the asn1RawMAPJSONConsumer - ProducerRecord r = - new ProducerRecord<>(rawEncodedMapJson, approvalTestCase.getInput()); - var sent = producer.send(r); - Awaitility.await().until(sent::isDone); + producer.send(rawEncodedMapJson, approvalTestCase.getInput()); - ConsumerRecord actualRecord = + var actualRecord = KafkaTestUtils.getSingleRecord(testConsumer, asn1DecoderInput); assertEquals(approvalTestCase.getExpected(), actualRecord.value(), approvalTestCase.getDescription()); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java index 5b44d0851..fe2a50a59 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/KafkaProducerConfigTest.java @@ -1,64 +1,52 @@ package us.dot.its.jpo.ode.kafka; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.util.Set; +import java.util.UUID; import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.admin.NewTopic; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.BeforeEach; +import org.apache.kafka.common.serialization.StringDeserializer; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Import; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.core.DefaultKafkaProducerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.core.ProducerFactory; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; -import us.dot.its.jpo.ode.kafka.producer.DisabledTopicException; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties.Producer; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.model.OdeObject; import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; @Slf4j -@SpringBootTest( - classes = { - KafkaProducerConfig.class, - OdeKafkaProperties.class, - KafkaProperties.class - } -) -@EnableConfigurationProperties +@ExtendWith(SpringExtension.class) +@DirtiesContext +@EnableConfigurationProperties({KafkaProperties.class}) +@Import({KafkaProducerConfigTest.KafkaProducerConfigTestConfig.class}) class KafkaProducerConfigTest { @Autowired + @Qualifier("testKafkaProducerConfig") KafkaProducerConfig kafkaProducerConfig; @Autowired + @Qualifier("testOdeKafkaProperties") OdeKafkaProperties odeKafkaProperties; - EmbeddedKafkaBroker embeddedKafka; - KafkaTemplate stringKafkaTemplate; - KafkaTemplate odeObjectKafkaTemplate; - - @BeforeEach - public void beforeClass() { - embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); - var topics = embeddedKafka.getTopics(); - for (String topic : odeKafkaProperties.getDisabledTopics()) { - if (!topics.contains(topic)) { - embeddedKafka.addTopics(new NewTopic(topic, 1, (short) 1)); - } - } - stringKafkaTemplate = - kafkaProducerConfig.kafkaTemplate(kafkaProducerConfig.producerFactory()); - odeObjectKafkaTemplate = - kafkaProducerConfig.odeDataKafkaTemplate(kafkaProducerConfig.odeDataProducerFactory()); - } + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); @Test void odeDataProducerFactory_shouldReturnNonNull() { @@ -77,18 +65,21 @@ void odeDataProducerFactory_shouldReturnDefaultKafkaProducerFactory() { @Test void kafkaTemplateInterceptorPreventsSendingToDisabledTopics() { + EmbeddedKafkaHolder.addTopics(odeKafkaProperties.getDisabledTopics().toArray(new String[0])); var consumerProps = KafkaTestUtils.consumerProps("interceptor-disabled", "false", embeddedKafka); - var cf = new DefaultKafkaConsumerFactory(consumerProps); + var cf = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); var consumer = cf.createConsumer(); - embeddedKafka.consumeFromAllEmbeddedTopics(consumer); - + embeddedKafka.consumeFromEmbeddedTopics(consumer, + odeKafkaProperties.getDisabledTopics().toArray(new String[0])); + KafkaTemplate stringKafkaTemplate = kafkaProducerConfig.kafkaTemplate( + kafkaProducerConfig.producerFactory()); // Attempting to send to a disabled topic for (String topic : odeKafkaProperties.getDisabledTopics()) { - assertThrows(DisabledTopicException.class, - () -> stringKafkaTemplate.send(topic, "key", "value")); + stringKafkaTemplate.send(topic, "key", "value"); var records = KafkaTestUtils.getEndOffsets(consumer, topic, 0); // Assert that the message we attempted to send to the disabled topic was intercepted @@ -104,20 +95,74 @@ void kafkaTemplateInterceptorPreventsSendingToDisabledTopics() { @Test void kafkaTemplateInterceptorAllowsSendingToTopicsNotInDisabledSet() { String enabledTopic = "topic.enabled" + this.getClass().getSimpleName(); - embeddedKafka.addTopics(new NewTopic(enabledTopic, 1, (short) 1)); + EmbeddedKafkaHolder.addTopics(enabledTopic); var consumerProps = KafkaTestUtils.consumerProps("interceptor-enabled", "false", embeddedKafka); - var cf = new DefaultKafkaConsumerFactory(consumerProps); + var cf = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); var consumer = cf.createConsumer(); embeddedKafka.consumeFromAnEmbeddedTopic(consumer, enabledTopic); // Attempting to send to a topic not in the disabledTopics set with the string template - var stringCompletableFuture = stringKafkaTemplate.send(enabledTopic, "key", "value"); - Awaitility.await().until(stringCompletableFuture::isDone); + KafkaTemplate stringKafkaTemplate = kafkaProducerConfig.kafkaTemplate( + kafkaProducerConfig.producerFactory()); + stringKafkaTemplate.send(enabledTopic, "key", "value"); + + var records = KafkaTestUtils.getRecords(consumer); + var produced = records.records(enabledTopic).iterator().next(); + assertEquals("key", produced.key()); + assertEquals("value", produced.value()); + } + + @Test + void kafkaTemplateInterceptorCanSendAfterAttemptToSendToDisabledTopic() { + String enabledTopic = "topic.enabled" + this.getClass().getSimpleName(); + EmbeddedKafkaHolder.addTopics(enabledTopic); - var records = KafkaTestUtils.getEndOffsets(consumer, enabledTopic, 0); - assertTrue(records.entrySet().stream().allMatch(e -> e.getValue() > 0L)); + var consumerProps = + KafkaTestUtils.consumerProps("send-after", "false", embeddedKafka); + var cf = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var consumer = cf.createConsumer(); + embeddedKafka.consumeFromAnEmbeddedTopic(consumer, enabledTopic); + + KafkaTemplate stringKafkaTemplate = kafkaProducerConfig.kafkaTemplate( + kafkaProducerConfig.producerFactory()); + var blockedTopic = odeKafkaProperties.getDisabledTopics().iterator().next(); + stringKafkaTemplate.send(blockedTopic, "blocked", "not sent"); + stringKafkaTemplate.send(enabledTopic, "key", "value"); + + var records = KafkaTestUtils.getRecords(consumer); + assertFalse(records.records(blockedTopic).iterator().hasNext()); + + var produced = records.records(enabledTopic).iterator().next(); + assertEquals("key", produced.key()); + assertEquals("value", produced.value()); } + @TestConfiguration + static class KafkaProducerConfigTestConfig { + + @Bean + public OdeKafkaProperties testOdeKafkaProperties() { + OdeKafkaProperties odeKafkaProperties = new OdeKafkaProperties(); + odeKafkaProperties.setBrokers("localhost:4242"); + odeKafkaProperties.setProducer(new Producer()); + var uniqueSuffix = UUID.randomUUID().toString().substring(0, 4); + odeKafkaProperties.setDisabledTopics(Set.of( + "topic.OdeBsmRxPojo" + uniqueSuffix, + "topic.OdeBsmTxPojo" + uniqueSuffix, + "topic.OdeBsmDuringEventPojo" + uniqueSuffix, + "topic.OdeTimBroadcastPojo" + uniqueSuffix + )); + + return odeKafkaProperties; + } + + @Bean + public KafkaProducerConfig testKafkaProducerConfig(KafkaProperties kafkaProperties, OdeKafkaProperties testOdeKafkaProperties) { + return new KafkaProducerConfig(kafkaProperties, testOdeKafkaProperties); + } + } } \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterApprovalTest.java similarity index 72% rename from jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java rename to jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterApprovalTest.java index 61b83e81f..ab70e7ee9 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterApprovalTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterApprovalTest.java @@ -1,4 +1,4 @@ -package us.dot.its.jpo.ode.services.asn1; +package us.dot.its.jpo.ode.kafka.listeners; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -7,26 +7,24 @@ import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; -import org.apache.kafka.clients.producer.Producer; -import org.apache.kafka.clients.producer.ProducerRecord; -import org.awaitility.Awaitility; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; -import org.springframework.kafka.core.DefaultKafkaProducerFactory; +import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import us.dot.its.jpo.ode.kafka.KafkaConsumerConfig; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.listeners.Asn1DecodedDataListener; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; import us.dot.its.jpo.ode.model.OdeMapData; import us.dot.its.jpo.ode.test.utilities.ApprovalTestCase; @@ -36,7 +34,7 @@ @Slf4j @SpringBootTest( classes = { - Asn1DecodedDataListener.class, + Asn1DecodedDataRouter.class, KafkaProperties.class, KafkaProducerConfig.class, KafkaConsumerConfig.class}, @@ -48,7 +46,8 @@ @EnableConfigurationProperties @ContextConfiguration(classes = { UDPReceiverProperties.class, OdeKafkaProperties.class, - RawEncodedJsonTopics.class, KafkaProperties.class + RawEncodedJsonTopics.class, KafkaProperties.class, + PojoTopics.class, JsonTopics.class }) @DirtiesContext class Asn1DecodedDataRouterApprovalTest { @@ -62,28 +61,20 @@ class Asn1DecodedDataRouterApprovalTest { @Value("${ode.kafka.topics.json.map}") private String jsonMapTopic; + @Autowired + KafkaTemplate producer; + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); @Test - void testAsn1DecodedDataRouter() throws IOException { - NewTopic inputTopic = new NewTopic(decoderOutputTopic, 1, (short) 1); - NewTopic outputTopicTx = new NewTopic(txMapTopic, 1, (short) 1); - NewTopic outputTopicJson = new NewTopic(jsonMapTopic, 1, (short) 1); - try { - embeddedKafka.addTopics(inputTopic, outputTopicTx, outputTopicJson); - } catch (Exception e) { - // Ignore. We only care that the topics exist not that we created them here - } + void testAsn1DecodedDataRouter_MAPDataFlow() throws IOException { + String[] topics = {decoderOutputTopic, txMapTopic, jsonMapTopic}; + EmbeddedKafkaHolder.addTopics(topics); @SuppressWarnings("checkstyle:linelength") List testCases = ApprovalTestCase.deserializeTestCases( "src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapTxPojo.json"); - Map producerProps = KafkaTestUtils.producerProps(embeddedKafka); - DefaultKafkaProducerFactory producerFactory = - new DefaultKafkaProducerFactory<>(producerProps); - Producer producer = producerFactory.createProducer(); - Map consumerProps = KafkaTestUtils.consumerProps("testT", "false", embeddedKafka); DefaultKafkaConsumerFactory cf = @@ -93,10 +84,7 @@ void testAsn1DecodedDataRouter() throws IOException { embeddedKafka.consumeFromEmbeddedTopics(consumer, txMapTopic, jsonMapTopic); for (ApprovalTestCase testCase : testCases) { - ProducerRecord producerRecord = - new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); - var sent = producer.send(producerRecord); - Awaitility.await().until(sent::isDone); + producer.send(decoderOutputTopic, testCase.getInput()); String received = KafkaTestUtils.getSingleRecord(consumer, txMapTopic).value(); ObjectMapper mapper = new ObjectMapper(); @@ -113,9 +101,7 @@ void testAsn1DecodedDataRouter() throws IOException { "src/test/resources/us.dot.its.jpo.ode.udp.map/Asn1DecoderRouter_ApprovalTestCases_MapJson.json"); for (ApprovalTestCase testCase : jsonTestCases) { - ProducerRecord producerRecord = - new ProducerRecord<>(decoderOutputTopic, 0, 0, testCase.getInput()); - producer.send(producerRecord); + producer.send(decoderOutputTopic, testCase.getInput()); String received = KafkaTestUtils.getSingleRecord(consumer, jsonMapTopic).value(); ObjectMapper mapper = new ObjectMapper(); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterTest.java new file mode 100644 index 000000000..ff484e269 --- /dev/null +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/kafka/listeners/Asn1DecodedDataRouterTest.java @@ -0,0 +1,417 @@ +package us.dot.its.jpo.ode.kafka.listeners; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicReference; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.serialization.StringDeserializer; +import org.assertj.core.util.Arrays; +import org.awaitility.Awaitility; +import org.awaitility.Duration; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.kafka.KafkaProperties; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; +import org.springframework.kafka.core.KafkaTemplate; +import org.springframework.kafka.test.EmbeddedKafkaBroker; +import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import us.dot.its.jpo.ode.kafka.KafkaConsumerConfig; +import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; +import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; +import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; +import us.dot.its.jpo.ode.kafka.topics.JsonTopics; +import us.dot.its.jpo.ode.kafka.topics.PojoTopics; +import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; +import us.dot.its.jpo.ode.model.OdeBsmData; +import us.dot.its.jpo.ode.test.utilities.EmbeddedKafkaHolder; +import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; +import us.dot.its.jpo.ode.wrapper.serdes.MessagingDeserializer; + +@Slf4j +@SpringBootTest( + classes = { + KafkaProperties.class, + PojoTopics.class, + JsonTopics.class, + Asn1CoderTopics.class, + KafkaConsumerConfig.class, + KafkaProducerConfig.class, + RawEncodedJsonTopics.class, + Asn1CoderTopics.class, + OdeKafkaProperties.class, + Asn1DecodedDataRouter.class + }, + properties = {"ode.kafka.disabled-topics="} +) +@EnableConfigurationProperties +@ContextConfiguration(classes = { + UDPReceiverProperties.class, OdeKafkaProperties.class, + PojoTopics.class, KafkaProperties.class +}) +@DirtiesContext +class Asn1DecodedDataRouterTest { + + EmbeddedKafkaBroker embeddedKafka = EmbeddedKafkaHolder.getEmbeddedKafka(); + @Autowired + KafkaTemplate kafkaStringTemplate; + @Autowired + PojoTopics pojoTopics; + @Autowired + JsonTopics jsonTopics; + @Autowired + Asn1CoderTopics asn1CoderTopics; + + ObjectMapper mapper = new ObjectMapper(); + + @Test + void testAsn1DecodedDataRouterBSMDataFlow() throws IOException { + String[] topics = Arrays.array( + pojoTopics.getBsm(), + pojoTopics.getBsmDuringEvent(), + pojoTopics.getRxBsm(), + pojoTopics.getTxBsm() + ); + EmbeddedKafkaHolder.addTopics(topics); + + var consumerProps = KafkaTestUtils.consumerProps( + "bsmDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory(consumerProps); + consumerFactory.setKeyDeserializer(new StringDeserializer()); + consumerFactory.setValueDeserializer(new MessagingDeserializer<>()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String decodedBsmXml = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-bsm.xml"); + OdeBsmData expectedBsm = mapper.readValue( + new File("src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-bsm.json"), + OdeBsmData.class); + for (String recordType : new String[] {"bsmLogDuringEvent", "rxMsg", "bsmTx"}) { + String topic; + switch (recordType) { + case "bsmLogDuringEvent" -> topic = pojoTopics.getBsmDuringEvent(); + case "rxMsg" -> topic = pojoTopics.getRxBsm(); + case "bsmTx" -> topic = pojoTopics.getTxBsm(); + default -> throw new IllegalStateException("Unexpected value: " + recordType); + } + + String inputData = replaceRecordType(decodedBsmXml, "bsmTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + AtomicReference> consumedSpecific = + new AtomicReference<>(); + AtomicReference> consumedBsm = new AtomicReference<>(); + Awaitility.await().until(() -> { + var records = KafkaTestUtils.getRecords(testConsumer); + for (ConsumerRecord cr : records.records(topic)) { + if (cr.key().equals(uniqueKey)) { + consumedSpecific.set(cr); + break; + } + } + for (ConsumerRecord cr : records.records(pojoTopics.getBsm())) { + if (cr.key().equals(uniqueKey)) { + consumedBsm.set(cr); + break; + } + } + return consumedSpecific.get() != null && consumedBsm.get() != null; + }); + assertEquals(expectedBsm, consumedSpecific.get().value()); + assertEquals(expectedBsm, consumedBsm.get().value()); + } + } + + @Test + void testAsn1DecodedDataRouterTIMDataFlow() { + Awaitility.setDefaultTimeout(Duration.FOREVER); + String[] topics = Arrays.array( + jsonTopics.getDnMessage(), + jsonTopics.getRxTim(), + jsonTopics.getTim() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-tim.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "timDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedTim = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-tim.json"); + for (String recordType : new String[] {"dnMsg", "rxMsg"}) { + String topic; + switch (recordType) { + case "rxMsg" -> topic = jsonTopics.getRxTim(); + case "dnMsg" -> topic = jsonTopics.getDnMessage(); + default -> throw new IllegalStateException("Unexpected value: " + recordType); + } + + String inputData = replaceRecordType(baseTestData, "timMsg", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + AtomicReference> consumedSpecific = new AtomicReference<>(); + AtomicReference> consumedTim = new AtomicReference<>(); + Awaitility.await().until(() -> { + var records = KafkaTestUtils.getRecords(testConsumer); + for (ConsumerRecord cr : records.records(topic)) { + if (cr.key().equals(uniqueKey)) { + consumedSpecific.set(cr); + break; + } + } + for (ConsumerRecord cr : records.records(jsonTopics.getTim())) { + if (cr.key().equals(uniqueKey)) { + consumedTim.set(cr); + break; + } + } + return consumedSpecific.get() != null && consumedTim.get() != null; + }); + var expectedTim = replaceJSONRecordType(baseExpectedTim, "dnMsg", recordType); + assertEquals(expectedTim, consumedSpecific.get().value()); + assertEquals(expectedTim, consumedTim.get().value()); + + } + } + + @Test + void testAsn1DecodedDataRouter_SPaTDataFlow() { + String[] topics = Arrays.array( + jsonTopics.getSpat(), + jsonTopics.getRxSpat(), + jsonTopics.getDnMessage(), + pojoTopics.getTxSpat() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-spat.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "spatDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedSpat = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-spat.json"); + for (String recordType : new String[] {"spatTx", "rxMsg", "dnMsg"}) { + String topic; + switch (recordType) { + case "rxMsg" -> topic = jsonTopics.getRxSpat(); + case "dnMsg" -> topic = jsonTopics.getDnMessage(); + case "spatTx" -> topic = pojoTopics.getTxSpat(); + default -> throw new IllegalStateException("Unexpected value: " + recordType); + } + + String inputData = replaceRecordType(baseTestData, "spatTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + var consumedSpecific = KafkaTestUtils.getSingleRecord(testConsumer, topic); + var consumedSpat = KafkaTestUtils.getSingleRecord(testConsumer, jsonTopics.getSpat()); + + var expectedSpat = replaceJSONRecordType(baseExpectedSpat, "spatTx", recordType); + assertEquals(expectedSpat, consumedSpat.value()); + assertEquals(expectedSpat, consumedSpecific.value()); + } + } + + @Test + void testAsn1DecodedDataRouter_SSMDataFlow() { + String[] topics = Arrays.array( + jsonTopics.getSsm(), + pojoTopics.getSsm() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-ssm.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "ssmDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedSsm = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-ssm.json"); + for (String recordType : new String[] {"ssmTx", "unsupported"}) { + + String inputData = replaceRecordType(baseTestData, "ssmTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + var expectedSsm = replaceJSONRecordType(baseExpectedSsm, "ssmTx", recordType); + + var consumedSsm = KafkaTestUtils.getSingleRecord(testConsumer, jsonTopics.getSsm()); + assertEquals(expectedSsm, consumedSsm.value()); + + if (recordType.equals("ssmTx")) { + var consumedSpecific = KafkaTestUtils.getSingleRecord(testConsumer, pojoTopics.getSsm()); + assertEquals(expectedSsm, consumedSpecific.value()); + } + } + } + + @Test + void testAsn1DecodedDataRouter_SRMDataFlow() { + String[] topics = Arrays.array( + jsonTopics.getSrm(), + pojoTopics.getTxSrm() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-srm.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "srmDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedSrm = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-srm.json"); + for (String recordType : new String[] {"srmTx", "unsupported"}) { + + String inputData = replaceRecordType(baseTestData, "srmTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + var expectedSrm = replaceJSONRecordType(baseExpectedSrm, "srmTx", recordType); + + var consumedSrm = KafkaTestUtils.getSingleRecord(testConsumer, jsonTopics.getSrm()); + assertEquals(expectedSrm, consumedSrm.value()); + + if (recordType.equals("srmTx")) { + var consumedSpecific = KafkaTestUtils.getSingleRecord(testConsumer, pojoTopics.getTxSrm()); + assertEquals(expectedSrm, consumedSpecific.value()); + } + } + } + + @Test + void testAsn1DecodedDataRouter_PSMDataFlow() { + String[] topics = Arrays.array( + jsonTopics.getPsm(), + pojoTopics.getTxPsm() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-psm.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "psmDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedPsm = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-psm.json"); + for (String recordType : new String[] {"psmTx", "unsupported"}) { + + String inputData = replaceRecordType(baseTestData, "psmTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + var expectedPsm = replaceJSONRecordType(baseExpectedPsm, "psmTx", recordType); + + var consumedPsm = KafkaTestUtils.getSingleRecord(testConsumer, jsonTopics.getPsm()); + assertEquals(expectedPsm, consumedPsm.value()); + + if (recordType.equals("psmTx")) { + var consumedSpecific = KafkaTestUtils.getSingleRecord(testConsumer, pojoTopics.getTxPsm()); + assertEquals(expectedPsm, consumedSpecific.value()); + } + } + } + + @Test + void testAsn1DecodedDataRouter_MAPDataFlow() { + String[] topics = Arrays.array( + jsonTopics.getMap(), + pojoTopics.getTxMap() + ); + EmbeddedKafkaHolder.addTopics(topics); + + String baseTestData = + loadFromResource("us/dot/its/jpo/ode/services/asn1/decoder-output-map.xml"); + + var consumerProps = KafkaTestUtils.consumerProps( + "mapDecoderTest", "false", embeddedKafka); + var consumerFactory = new DefaultKafkaConsumerFactory<>(consumerProps, + new StringDeserializer(), new StringDeserializer()); + var testConsumer = consumerFactory.createConsumer(); + embeddedKafka.consumeFromEmbeddedTopics(testConsumer, topics); + + String baseExpectedMap = + loadFromResource("us/dot/its/jpo/ode/services/asn1/expected-map.json"); + for (String recordType : new String[] {"mapTx", "unsupported"}) { + + String inputData = replaceRecordType(baseTestData, "mapTx", recordType); + var uniqueKey = UUID.randomUUID().toString(); + kafkaStringTemplate.send(asn1CoderTopics.getDecoderOutput(), uniqueKey, inputData); + + var expectedMap = replaceJSONRecordType(baseExpectedMap, "mapTx", recordType); + + var consumedMap = KafkaTestUtils.getSingleRecord(testConsumer, jsonTopics.getMap()); + assertEquals(expectedMap, consumedMap.value()); + + if (recordType.equals("mapTx")) { + var consumedSpecific = KafkaTestUtils.getSingleRecord(testConsumer, pojoTopics.getTxMap()); + assertEquals(expectedMap, consumedSpecific.value()); + } + } + } + + private String loadFromResource(String resourcePath) { + String baseTestData; + try (InputStream inputStream = getClass().getClassLoader() + .getResourceAsStream(resourcePath)) { + if (inputStream == null) { + throw new FileNotFoundException("Resource not found: " + resourcePath); + } + baseTestData = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new RuntimeException("Failed to load test data", e); + } + return baseTestData; + } + + private String replaceRecordType(String testData, String curRecordType, String recordType) { + return testData.replace("" + curRecordType + "", + "" + recordType + ""); + } + + private String replaceJSONRecordType(String testData, String curRecordType, String recordType) { + return testData.replace("\"recordType\":\"" + curRecordType + "\"", + "\"recordType\":\"" + recordType + "\""); + } +} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java deleted file mode 100644 index 1350a875e..000000000 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/services/asn1/Asn1DecodedDataRouterTest.java +++ /dev/null @@ -1,394 +0,0 @@ -/******************************************************************************* - * Copyright 2018 572682 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - ******************************************************************************/ -package us.dot.its.jpo.ode.services.asn1; - -import java.util.Set; - -import org.apache.kafka.clients.consumer.ConsumerRecord; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import mockit.Expectations; -import mockit.Mocked; -import mockit.Tested; -import us.dot.its.jpo.ode.model.OdeBsmData; -import us.dot.its.jpo.ode.plugin.j2735.J2735DSRCmsgID; -import us.dot.its.jpo.ode.util.XmlUtils; -import us.dot.its.jpo.ode.util.XmlUtils.XmlUtilsException; -import us.dot.its.jpo.ode.wrapper.MessageProducer; - -public class Asn1DecodedDataRouterTest { - - @Tested - Asn1DecodedDataRouter testAsn1DecodedDataRouter; - - -// @SuppressWarnings("rawtypes") -// @Capturing -// MessageProducer capturingMessageProducer; -// -// @Capturing -// XmlUtils capturingXmlUtils; -// -// @Capturing -// OdeBsmDataCreatorHelper capturingOdeBsmDataCreatorHelper; - - @Mocked - MessageProducer mockBsmMessageProducer; - @Mocked - MessageProducer mockTimMessageProducer; - - @Mocked - JSONObject mockConsumed; - @Mocked - ConsumerRecord mockConsumerRecord; - - @SuppressWarnings("unchecked") - @BeforeEach @Disabled - public void createMockProducers() { - - new Expectations() { - { - new MessageProducer(null, null, null, anyString, (Set) any); - result = mockBsmMessageProducer; - - MessageProducer.defaultStringMessageProducer(null, null, (Set) any); - result = mockTimMessageProducer; - - } - }; - } - - @Test @Disabled - public void testProcessBsmLogDuringEvent() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.BasicSafetyMessage.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "bsmLogDuringEvent"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 2; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 0; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessRxMsgBsm() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.BasicSafetyMessage.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "rxMsg"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 2; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 0; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessTxMsgBsm() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.BasicSafetyMessage.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "bsmTx"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 2; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 0; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessDnsTim() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.TravelerInformation.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "dnMsg"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 0; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 2; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessRxTim() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.TravelerInformation.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "rxMsg"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 0; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 2; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessUnsupportedTim() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.TravelerInformation.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "unsupported"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 0; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 1; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - @Test @Disabled - public void testProcessUnsupportedBsm() throws XmlUtilsException { - try { - new Expectations() { - - { - XmlUtils.toJSONObject(anyString); - result = mockConsumed; - - mockConsumed.getJSONObject(anyString); - result = mockConsumed; - - // mock the messageID to be BSM - mockConsumed.getInt(anyString); - result = J2735DSRCmsgID.BasicSafetyMessage.getMsgID(); - - // mock the record type to be bsmLogDuringEvent - mockConsumed.getString(anyString); - result = "unsupported"; - - mockConsumerRecord.key(); - result = "testKey"; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 1; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 0; - } - }; - } catch (XmlUtilsException e) { - - e.printStackTrace(); - } catch (JSONException e) { - - e.printStackTrace(); - } - - testAsn1DecodedDataRouter.setRecord(mockConsumerRecord); - testAsn1DecodedDataRouter.process("testConsumedData"); - } - - - @Test @Disabled - public void testProcessXmlException() throws XmlUtilsException { - new Expectations() { - - @Mocked - XmlUtilsException mockXmlUtilsException; - - { - XmlUtils.toJSONObject(anyString); - result = mockXmlUtilsException; - - mockBsmMessageProducer.send(null, anyString, (OdeBsmData) any); - times = 0; - - mockTimMessageProducer.send(null, anyString, anyString); - times = 0; - } - }; - - testAsn1DecodedDataRouter.process("testConsumedData"); - } -} diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java index f87d5ddbb..95fcc5366 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/test/utilities/EmbeddedKafkaHolder.java @@ -1,5 +1,7 @@ package us.dot.its.jpo.ode.test.utilities; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.admin.NewTopic; import org.springframework.kafka.KafkaException; import org.springframework.kafka.test.EmbeddedKafkaBroker; @@ -9,8 +11,7 @@ * throughout the application lifecycle. * *

This class initializes an embedded Kafka broker with a specified configuration, which - * includes - * a single broker and auto-start enabled. The broker list property is set to + * includes a single broker and auto-start enabled. The broker list property is set to * "spring.kafka.bootstrap-servers". * *

The embedded Kafka instance is lazily started when the getEmbeddedKafka method is called @@ -18,6 +19,7 @@ * *

The class is designed to be non-instantiable with a private constructor. */ +@Slf4j public final class EmbeddedKafkaHolder { private static final EmbeddedKafkaBroker embeddedKafka = new EmbeddedKafkaBroker(1, @@ -48,6 +50,25 @@ public static EmbeddedKafkaBroker getEmbeddedKafka() { return embeddedKafka; } + /** + * Adds one or more topics to the embedded Kafka broker instance. Each topic will be created + * with a replication factor of 1 and a single partition. If a topic already exists, no action + * is taken, and the exception is ignored. + * + * @param topics one or more topic names to be added to the embedded Kafka broker + */ + public static void addTopics(String... topics) { + for (String topic : topics) { + NewTopic newTopic = new NewTopic(topic, 1, (short) 1); + try { + embeddedKafka.addTopics(newTopic); + } catch (Exception e) { + // Ignore because we only care they are created not that they weren't created prior + log.debug("exception adding topic {} to embedded kafka broker", topic, e); + } + } + } + private EmbeddedKafkaHolder() { super(); } diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java index 50fb5583f..832bdcc4e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/bsm/BsmReceiverTest.java @@ -10,11 +10,9 @@ import java.time.ZoneId; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -23,8 +21,8 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; @@ -33,7 +31,6 @@ import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -@RunWith(SpringRunner.class) @EnableConfigurationProperties @SpringBootTest( classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, @@ -46,6 +43,7 @@ UDPReceiverProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class BsmReceiverTest { @Autowired @@ -61,12 +59,7 @@ class BsmReceiverTest { @Test void testRun() throws Exception { - // create the needed topic for production - try { - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getBsm(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topics exist not that they're unique - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getBsm()); DateTimeUtils.setClock( Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java index 684cedc3a..d27a13de7 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/generic/GenericReceiverTest.java @@ -10,10 +10,8 @@ import java.time.ZoneOffset; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -22,8 +20,8 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; @@ -32,7 +30,6 @@ import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -@RunWith(SpringRunner.class) @EnableConfigurationProperties @SpringBootTest( classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, @@ -51,6 +48,7 @@ UDPReceiverProperties.class, OdeKafkaProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class GenericReceiverTest { @Autowired @@ -66,20 +64,16 @@ class GenericReceiverTest { @Test void testRun() throws Exception { - try { - embeddedKafka.addTopics( - new NewTopic(rawEncodedJsonTopics.getBsm(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getMap(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getPsm(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getSpat(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getSsm(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getTim(), 1, (short) 1), - new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1) - ); - } catch (Exception e) { - // Ignore topic creation exceptions - } + String[] topics = { + rawEncodedJsonTopics.getBsm(), + rawEncodedJsonTopics.getMap(), + rawEncodedJsonTopics.getPsm(), + rawEncodedJsonTopics.getSpat(), + rawEncodedJsonTopics.getSsm(), + rawEncodedJsonTopics.getTim(), + rawEncodedJsonTopics.getSrm() + }; + EmbeddedKafkaHolder.addTopics(topics); GenericReceiver genericReceiver = new GenericReceiver( udpReceiverProperties.getGeneric(), @@ -95,15 +89,7 @@ void testRun() throws Exception { var consumerProps = KafkaTestUtils.consumerProps("GenericReceiverTest", "true", embeddedKafka); var cf = new DefaultKafkaConsumerFactory(consumerProps); var consumer = cf.createConsumer(); - embeddedKafka.consumeFromEmbeddedTopics(consumer, - rawEncodedJsonTopics.getMap(), - rawEncodedJsonTopics.getSsm(), - rawEncodedJsonTopics.getPsm(), - rawEncodedJsonTopics.getSpat(), - rawEncodedJsonTopics.getTim(), - rawEncodedJsonTopics.getBsm(), - rawEncodedJsonTopics.getSrm() - ); + embeddedKafka.consumeFromEmbeddedTopics(consumer, topics); DateTimeUtils.setClock(Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneOffset.UTC)); @@ -172,7 +158,8 @@ void testRun() throws Exception { Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ValidData.txt") ); String expectedSrm = Files.readString( - Paths.get("src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json") + Paths.get( + "src/test/resources/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest_ExpectedOutput.json") ); udpClient.send(srmFileContent); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java index d5fedb099..ce0252d7e 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/map/MapReceiverTest.java @@ -12,7 +12,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import lombok.extern.slf4j.Slf4j; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.json.JSONObject; @@ -79,13 +78,7 @@ void testMapReceiver() throws IOException { ExecutorService executorService = Executors.newCachedThreadPool(); executorService.submit(mapReceiver); - try { - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getMap(), 1, (short) 1)); - } catch (Exception e) { - log.warn( - "Couldn't create topics. If the error indicates the topics already exist, this message is safe to ignore: {}", - e.getMessage()); - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getMap()); // Set up a Kafka consumer Map consumerProps = diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java index d1b3f51ad..2ce768aed 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/psm/PsmReceiverTest.java @@ -22,6 +22,7 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; @@ -45,6 +46,7 @@ UDPReceiverProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class PsmReceiverTest { @Autowired diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java index 8aa9abe84..d5e6727fa 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/spat/SpatReceiverTest.java @@ -10,11 +10,9 @@ import java.time.ZoneId; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -23,8 +21,8 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; @@ -33,7 +31,6 @@ import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -@RunWith(SpringRunner.class) @EnableConfigurationProperties @SpringBootTest( classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, @@ -46,6 +43,7 @@ UDPReceiverProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class SpatReceiverTest { @Autowired @@ -61,12 +59,7 @@ class SpatReceiverTest { @Test void testRun() throws Exception { - - try { - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSpat(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topics exist not that they're unique - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getSpat()); DateTimeUtils.setClock( Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java index ea0723955..6cea58e2b 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/srm/SrmReceiverTest.java @@ -10,7 +10,6 @@ import java.time.ZoneId; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.json.JSONObject; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; @@ -22,6 +21,7 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; @@ -45,6 +45,7 @@ UDPReceiverProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class SrmReceiverTest { @Autowired @@ -60,12 +61,7 @@ class SrmReceiverTest { @Test void testRun() throws Exception { - - try { - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSrm(), 1, (short) 1)); - } catch (Exception e) { - // Ignore - ensure topic existence - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getSrm()); DateTimeUtils.setClock( Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java index f8844d312..7217865a5 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/ssm/SsmReceiverTest.java @@ -10,11 +10,9 @@ import java.time.ZoneId; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -23,8 +21,8 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; @@ -33,7 +31,6 @@ import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -@RunWith(SpringRunner.class) @EnableConfigurationProperties @SpringBootTest( classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, @@ -46,6 +43,7 @@ UDPReceiverProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class SsmReceiverTest { @Autowired @@ -61,11 +59,7 @@ class SsmReceiverTest { @Test void testRun() throws Exception { - try { - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getSsm(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topics exist not that they're unique - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getSsm()); DateTimeUtils.setClock( Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java index e11f96254..d23bdab88 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/udp/tim/TimReceiverTest.java @@ -10,11 +10,9 @@ import java.time.ZoneId; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.kafka.clients.admin.NewTopic; import org.apache.kafka.clients.consumer.Consumer; import org.json.JSONObject; import org.junit.jupiter.api.Test; -import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -23,8 +21,8 @@ import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.test.EmbeddedKafkaBroker; import org.springframework.kafka.test.utils.KafkaTestUtils; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.producer.KafkaProducerConfig; import us.dot.its.jpo.ode.kafka.topics.RawEncodedJsonTopics; @@ -33,7 +31,6 @@ import us.dot.its.jpo.ode.udp.controller.UDPReceiverProperties; import us.dot.its.jpo.ode.util.DateTimeUtils; -@RunWith(SpringRunner.class) @EnableConfigurationProperties @SpringBootTest( classes = {OdeKafkaProperties.class, UDPReceiverProperties.class, KafkaProducerConfig.class}, @@ -46,6 +43,7 @@ UDPReceiverProperties.class, OdeKafkaProperties.class, RawEncodedJsonTopics.class, KafkaProperties.class }) +@DirtiesContext class TimReceiverTest { @Autowired @@ -61,12 +59,7 @@ class TimReceiverTest { @Test void testRun() throws Exception { - try { - - embeddedKafka.addTopics(new NewTopic(rawEncodedJsonTopics.getTim(), 1, (short) 1)); - } catch (Exception e) { - // ignore because we only care that the topics exist not that they're unique - } + EmbeddedKafkaHolder.addTopics(rawEncodedJsonTopics.getTim()); DateTimeUtils.setClock( Clock.fixed(Instant.parse("2024-11-26T23:53:21.120Z"), ZoneId.of("UTC"))); diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-bsm.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-bsm.xml new file mode 100644 index 000000000..e7e98cd4a --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-bsm.xml @@ -0,0 +1,235 @@ + + + + EV + + bsmTx + success + + + unavailable + unavailable + unavailable + unavailable + unavailable + + RSU + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + 71406f1b-d33c-4e90-ace9-6ab9f8d116d0 + 1 + 0 + 0 + 0 + + 2024-12-10T17:30:48.095Z + 7 + 0 + + OBU + false + + + + 001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00 + + 172.18.0.1 + + + MessageFrame + + + 20 + + + + 37 + 31325433 + 25399 + 405659938 + -1050317754 + 14409 + + 186 + 241 + 65535 + + + + + 14 + 25060 + 127 + + 27 + 0 + 0 + 0 + + + 10000 + + + + + + + + + + + + + + + + + + 190 + 570 + + + + + 0 + + + + + + -113 + 181 + -6 + 190 + + + -310 + 472 + -23 + 610 + + + -103 + 636 + -14 + 1570 + + + -52 + 615 + -13 + 1870 + + + 614 + 1150 + -17 + 2589 + + + 1878 + 2503 + 7 + 3959 + + + 2333 + 2816 + 31 + 4539 + + + 2187 + 2952 + 39 + 4959 + + + 1976 + 2721 + 46 + 5699 + + + 1891 + 3655 + 84 + 6050 + + + 2022 + 4886 + 137 + 6349 + + + 1973 + 4861 + 144 + 6760 + + + 1795 + 4815 + 144 + 7270 + + + 1710 + 4749 + 135 + 7570 + + + 1609 + 4566 + 121 + 7880 + + + + + 32767 + 0 + + + + + + 2 + + + + 0 + + + + + + + 0 + + + 38 + + + 191 + + + + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-map.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-map.xml new file mode 100644 index 000000000..323fa804a --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-map.xml @@ -0,0 +1,1707 @@ + + + + + mapTx + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + 2bc6b4d1-8534-482c-9004-18a4d2613622 + 1 + 0 + 0 + 0 + + 2024-12-10T17:32:22.024Z + 7 + 0 + + RSU + false + + + + 001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E00 + + RSU + 172.18.0.1 + + + MessageFrame + + + 18 + + + 0 + + + + 0 + + + + 12110 + + 0 + + 395952649 + -1050914122 + 16770 + + 366 + + + 2 + 1 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + 2225 + 808 + + + + -10 + + + + + + 10517 + -161 + + + + -60 + + + + + + 2769 + 112 + + + + -10 + + + + + + 6142 + -180 + + + + -30 + + + + + + 6636 + -12 + + + + -20 + + + + + + 3804 + -7 + + + + + + + + + 19 + 100000000000 + + 4 + 1 + + + + + 3 + 1 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + 2222 + 515 + + + + -10 + + + + + + 2933 + -82 + + + + -10 + + + + + + 6259 + -85 + + + + -40 + + + + + + 3416 + -98 + + + + -20 + + + + + + 6867 + -39 + + + + -30 + + + + + + 2657 + -55 + + + + -10 + + + + + + 4259 + 67 + + + + -10 + + + + + + 3481 + 0 + + + + + + + + + 18 + 100000000000 + + 4 + 1 + + + + + 1 + 1 + + 10 + 0000000000 + + 00000000 + + + 001000000000 + + + + + + 2215 + 1218 + + + + + + + 10451 + -223 + + + + -70 + + + + + + 1852 + -108 + + + + -10 + + + + + + + + 28 + 001000000000 + + 1 + + + + + 4 + 1 + + 10 + 0000000000 + + 00000000 + + + 010000000000 + + + + + + 2213 + -124 + + + + -10 + + + + + + 7187 + 20 + + + + -40 + + + + + + 541 + 40 + + + + -10 + + + + + + 1298 + 229 + + + + + + + + + 12 + 010000000000 + + 7 + 1 + + + + + 6 + 2 + + 01 + 0000000000 + + 00000000 + + + + + + + + 2267 + -1019 + + + + -10 + + + + + + 365 + 7 + + + + + + + + 5 + 2 + + 01 + 0000000000 + + 00000000 + + + + + + + + 2267 + -662 + + + + -10 + + + + + + 338 + 0 + + + + + + + + 7 + 2 + + 01 + 0000000000 + + 00000000 + + + + + + + + 2294 + -1463 + + + + -10 + + + + + + 365 + 27 + + + + + + + + 12 + 4 + + 01 + 0000000000 + + 00000000 + + + + + + + + -952 + -1898 + + + + + + + 0 + -377 + + + + + + + + 13 + 4 + + 01 + 0000000000 + + 00000000 + + + + + + + + -1440 + -1898 + + + + + + + 7 + -390 + + + + + + + 0 + 0 + + + + + + + 0 + 7 + + + + + + + + 10 + 3 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + 705 + -1919 + + + + + + + -1 + -7515 + + + + -40 + + + + + + -41 + -5272 + + + + 10 + + + + + + -17 + -11337 + + + + + + + 17 + -5938 + + + + 10 + + + + + + 0 + 0 + + + + + + + -7 + -7 + + + + + + + + + 26 + 100000000000 + + 6 + 1 + + + + + 9 + 3 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + 1090 + -1930 + + + + -10 + + + + + + 9 + -4764 + + + + -10 + + + + + + -20 + -6402 + + + + -20 + + + + + + -34 + -7953 + + + + -10 + + + + + + 16 + -10940 + + + + 20 + + + + + + + + 27 + 100000000000 + + 6 + 1 + + + + + 11 + 3 + + 10 + 0000000000 + + 00000000 + + + 010000000000 + + + + + + 350 + -1925 + + + + + + + -32 + -6698 + + + + -30 + + + + + + 156 + -2616 + + + + + + + + + 18 + 010000000000 + + 1 + 1 + + + + + 8 + 3 + + 10 + 0000000000 + + 00000000 + + + 001000000000 + + + + + + 1557 + -1956 + + + + -10 + + + + + + -101 + -1956 + + + + + + + -5 + -7393 + + + + -40 + + + + + + -121 + -1636 + + + + + + + + + 7 + 001000000000 + + 1 + + + + + 15 + 5 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + -2405 + -1018 + + + + 10 + + + + + + -9339 + 26 + + + + 30 + + + + + + -11895 + -38 + + + + 50 + + + + + + -8814 + 13 + + + + + + + + + 6 + 100000000000 + + 8 + 1 + + + + + 16 + 5 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + -2337 + -656 + + + + 10 + + + + + + -12229 + 15 + + + + 50 + + + + + + -11362 + -37 + + + + 30 + + + + + + -6537 + 1 + + + + + + + + + 5 + 100000000000 + + 8 + 1 + + + + + 17 + 5 + + 10 + 0000000000 + + 00002024-12-10T17:32:22.099782646Z 0000 + + + 010000000000 + + + + + + -2338 + -284 + + + + 10 + + + + + + -8892 + -18 + + + + 30 + + + + + + -11959 + -2 + + + + 50 + + + + + + -1564 + -180 + + + + + + + + + 26 + 010000000000 + + 3 + 1 + + + + + 14 + 5 + + 10 + 0000000000 + + 00000000 + + + 001000000000 + + + + + + -2401 + -1380 + + + + 10 + + + + + + -19947 + 8 + + + + 80 + + + + + + -10108 + -7 + + + + + + + + + 13 + 001000000000 + + 1 + + + + + 18 + 6 + + 01 + 0000000000 + + 00000000 + + + + + + + + -2264 + 479 + + + + 20 + + + + + + -580 + -14 + + + + + + + + 19 + 6 + + 01 + 0000000000 + + 00000000 + + + + + + + + -2257 + 796 + + + + 20 + + + + + + -518 + 0 + + + + + + + + 20 + 6 + + 01 + 0000000000 + + 00000000 + + + + + + + + -2236 + 1229 + + + + 20 + + + + + + -484 + 0 + + + + + + + + 23 + 7 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + -914 + 1903 + + + + 20 + + + + + + 225 + 12288 + + + + 30 + + + + + + 40 + 9634 + + + + -20 + + + + + + 32 + 8035 + + + + -30 + + + + + + 0 + 0 + + + + + + + -7 + 28 + + + + + + + + + 12 + 100000000000 + + 2 + 1 + + + + + 22 + 7 + + 10 + 0000000000 + + 00000000 + + + 100000000000 + + + + + + -1221 + 1914 + + + + 20 + + + + + + 92 + 10475 + + + + 30 + + + + + + 89 + 11582 + + + + -20 + + + + + + 48 + 7912 + + + + -30 + + + + + + + + 13 + 100000000000 + + 2 + 1 + + + + + 21 + 7 + + 10 + 0000000000 + + 00000000 + + + 001000000000 + + + + + + -1649 + 1935 + + + + 20 + + + + + + 16 + 3182 + + + + 10 + + + + + + 21 + 5991 + + + + 20 + + + + + + 102 + 4810 + + + + + + + 85 + 11803 + + + + -30 + + + + + + 19 + 4161 + + + + -20 + + + + + + + + 20 + 001000000000 + + 1 + + + + + 24 + 7 + + 10 + 0000000000 + + 00000000 + + + 010000000000 + + + + + + -535 + 1926 + + + + 20 + + + + + + 28 + 4582 + + + + 10 + + + + + + 88 + 3793 + + + + 10 + + + + + + -143 + 1866 + + + + 10 + + + + + + + + 6 + 010000000000 + + 5 + 1 + + + + + 25 + 7 + + 10 + 0000000000 + + 00000000 + + + 010000000000 + + + + + + -213 + 1913 + + + + 20 + + + + + + 14 + 4594 + + + + 10 + + + + + + -91 + 2238 + + + + 10 + + + + + + + + 5 + 010000000000 + + 5 + 1 + + + + + 26 + 8 + + 01 + 0000000000 + + 00000000 + + + + + + + + 724 + 1902 + + + + 10 + + + + + + -7 + 352 + + + + 10 + + + + + + + 27 + 8 + + 01 + 0000000000 + + 00000000 + + + + + + + + 1105 + 1888 + + + + 10 + + + + + + -7 + 332 + + + + 10 + + + + + + + 28 + 8 + + 01 + 0000000000 + + 00000000 + + + + + + + + 1591 + 1874 + + + + 10 + + + + + + -14 + 346 + + + + + + + 0 + 7 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-psm.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-psm.xml new file mode 100644 index 000000000..129b7c280 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-psm.xml @@ -0,0 +1,65 @@ + + + + + psmTx + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + 9219cf4d-66e3-4b65-8981-b56b50688023 + 1 + 0 + 0 + 0 + + 2024-12-10T17:33:49.421Z + 7 + 0 + + UNKNOWN + false + + + 00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100 + + RSU + 172.18.0.1 + + + MessageFrame + + + 32 + + + + + + 3564 + 26 + 24779D7E + + 402397377 + -742761437 + + + 20 + 20 + 8191 + + 0 + 8898 + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-spat.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-spat.xml new file mode 100644 index 000000000..07c2303f7 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-spat.xml @@ -0,0 +1,146 @@ + + + + + spatTx + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + a80d7125-d548-4114-b435-ce890b8906d3 + 1 + 0 + 0 + 0 + + 2024-12-10T17:34:40.359Z + 7 + 0 + + RSU + false + + + + 001338000817A780000089680500204642B342B34802021A15A955A940181190ACD0ACD20100868555C555C00104342AAE2AAE002821A15571557000 + + RSU + 172.18.0.1 + false + + + MessageFrame + + + 19 + + + + + + 12111 + + 0 + 0000000000000000 + 35176 + + + 2 + + + + + + + 22120 + 22121 + + + + + + 4 + + + + + + + 22181 + 22181 + + + + + + 6 + + + + + + + 22120 + 22121 + + + + + + 8 + + + + + + + 21852 + 21852 + + + + + + 1 + + + + + + + 21852 + 21852 + + + + + + 5 + + + + + + + 21852 + 21852 + + + + + + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-srm.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-srm.xml new file mode 100644 index 000000000..0f1fa7233 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-srm.xml @@ -0,0 +1,87 @@ + + + + + srmTx + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + 48e23a19-c438-4e97-a54e-150cdf10afe1 + 1 + 0 + 0 + 0 + + 2024-12-10T17:35:36.923Z + 7 + 0 + + OBU + false + + + 001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000 + 172.18.0.1 + RSU + + + MessageFrame + + + 29 + + + 0 + 1 + + + + + 12109 + + 4 + + + + + 13 + + + 4 + + + 10979 + + + + + 2366845094 + + + + + + + + + 395904915 + -1050913829 + 16854 + + 14072 + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-ssm.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-ssm.xml new file mode 100644 index 000000000..05c67bc6f --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-ssm.xml @@ -0,0 +1,78 @@ + + + + + ssmTx + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + b04f6d45-d1f2-4cfb-8a6c-f542bbd0aa51 + 1 + 0 + 0 + 0 + + 2024-12-10T17:36:31.804Z + 7 + 0 + + RSU + false + + + 001E120000000005E9C04071A26614C06000040BA000 + 172.18.0.1 + RSU + + + MessageFrame + + + 30 + + + 0 + + + 0 + + 12110 + + + + + + 2366845094 + + 3 + 0 + + + + + + + + 23 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-tim.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-tim.xml new file mode 100644 index 000000000..ad0dbe37b --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/decoder-output-tim.xml @@ -0,0 +1,214 @@ + + + + + timMsg + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + d1475b66-9f6d-4a85-a4bd-bc54a825fb0f + 1 + 0 + 0 + 0 + + 2024-12-10T17:20:48.699Z + 7 + 0 + + RSU + false + + + + 03810040038081D4001F80D07016DA410000000000000BBC2B0F775D9B0309C271431FA166EE0A27FFF93F136B8205A0A107FB2EF979F4C5BFAEEC97E4AD70C2FB36CD9730BECDB355CC2FD2A7556B160B98B46AB98AE62C185FA55EFB468D5B4000000004E2863F42CDDC144FF7980040401262CDD7B809C509F5C62CDD35519C507B9062CDCEE129C505CF262CDCA5FF9C50432C62CDC5D3D9C502E3E62CDC13E79C501E9262CDBCA2D9C5013EE62CDB80359C500E6A62CDB36299C500BC862CDAEC1D9C50093C62CDAA2109C5006EA1080203091A859EEEBB36006001830001AAD27F4FF7580001AAD355E39B5880A30029D6585009EF808332D8D9F80C3855151B38C772F765007967EC1170BCB7937F5CB880A25A52863493BCB87570DBCB5ABC6BFB2FAEC606CFA34EB95A24790B2017366D3AABE7729E00 + + 172.18.0.1 + + + MessageFrame + + + 31 + + + 1 + 449089 + 0000000000000BBC2B + null + + + 1 + + + + + + + 411269876 + -1047269563 + + 1111111111111111 + + + + + + 2018 + 448260 + 1440 + 5 + 1 + + + westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456 + + 0 + 0 + + + 411269876 + -1047269563 + + 32700 + + + + + + + 0000000000010000 + + + 0 + + + + + + + -1047287423 + 411264686 + + + + + + + -1047305390 + 411260104 + + + + + + + -1047323629 + 411256185 + + + + + + + -1047342080 + 411252886 + + + + + + + -1047360706 + 411250207 + + + + + + + -1047379480 + 411248201 + + + + + + + -1047398354 + 411246839 + + + + + + + -1047417290 + 411246133 + + + + + + + -1047436246 + 411245796 + + + + + + + -1047455202 + 411245470 + + + + + + + -1047474159 + 411245173 + + + + + + + + + + + 1 + 1 + + + + + 777 + + + + + 13579 + + + + + null + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-bsm.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-bsm.json new file mode 100644 index 000000000..c546a6f3e --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-bsm.json @@ -0,0 +1,83 @@ +{ + "metadata": { + "bsmSource": "EV", + "logFileName": "", + "recordType": "bsmLogDuringEvent", + "securityResultCode": "success", + "receivedMessageDetails": { + "locationData": { + "latitude": "unavailable", + "longitude": "unavailable", + "elevation": "unavailable", + "speed": "unavailable", + "heading": "unavailable" + }, + "rxSource": "RSU" + }, + "payloadType": "us.dot.its.jpo.ode.model.OdeBsmPayload", + "serialId": { + "streamId": "71406f1b-d33c-4e90-ace9-6ab9f8d116d0", + "bundleSize": 1, + "bundleId": 0, + "recordId": 0, + "serialNumber": 0 + }, + "odeReceivedAt": "2024-12-10T17:30:48.095Z", + "schemaVersion": 7, + "maxDurationTime": 0, + "recordGeneratedAt": "", + "recordGeneratedBy": "OBU", + "sanitized": false, + "odePacketID": "", + "odeTimStartDateTime": "", + "asn1": "001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00", + "originIp": "172.18.0.1" + }, + "payload": { + "data": { + "coreData": { + "msgCnt": 37, + "id": "31325433", + "secMark": 25399, + "position": { + "latitude": 40.5659938, + "longitude": -105.0317754, + "elevation": 1440.9 + }, + "accelSet": { + "accelLat": 0.00, + "accelLong": 0.27, + "accelVert": 0.00, + "accelYaw": 0.00 + }, + "accuracy": { + "semiMajor": 9.30, + "semiMinor": 12.05 + }, + "transmission": "UNAVAILABLE", + "speed": 0.28, + "heading": 313.2500, + "brakes": { + "wheelBrakes": { + "leftFront": false, + "rightFront": false, + "unavailable": true, + "leftRear": false, + "rightRear": false + }, + "traction": "unavailable", + "abs": "unavailable", + "scs": "unavailable", + "brakeBoost": "unavailable", + "auxBrakes": "unavailable" + }, + "size": { + "width": 190, + "length": 570 + } + }, + "partII": [] + }, + "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735Bsm" + } +} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-map.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-map.json new file mode 100644 index 000000000..c975b08b4 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-map.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"mapTx","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeMapPayload","serialId":{"streamId":"2bc6b4d1-8534-482c-9004-18a4d2613622","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:32:22.024Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E00","mapSource":"RSU","originIp":"172.18.0.1"},"payload":{"data":{"msgIssueRevision":0,"layerType":"intersectionData","layerID":0,"intersections":{"intersectionGeometry":[{"id":{"id":12110},"revision":0,"refPoint":{"latitude":39.5952649,"longitude":-105.0914122,"elevation":1677.0},"laneWidth":366,"laneSet":{"GenericLane":[{"laneID":2,"ingressApproach":1,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2225,"y":808}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":10517,"y":-161}},"attributes":{"dElevation":-60}},{"delta":{"nodeXY6":{"x":2769,"y":112}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":6142,"y":-180}},"attributes":{"dElevation":-30}},{"delta":{"nodeXY6":{"x":6636,"y":-12}},"attributes":{"dElevation":-20}},{"delta":{"nodeXY6":{"x":3804,"y":-7}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":19,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":4,"connectionID":1}]}},{"laneID":3,"ingressApproach":1,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2222,"y":515}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":2933,"y":-82}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":6259,"y":-85}},"attributes":{"dElevation":-40}},{"delta":{"nodeXY6":{"x":3416,"y":-98}},"attributes":{"dElevation":-20}},{"delta":{"nodeXY6":{"x":6867,"y":-39}},"attributes":{"dElevation":-30}},{"delta":{"nodeXY6":{"x":2657,"y":-55}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":4259,"y":67}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":3481,"y":0}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":18,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":4,"connectionID":1}]}},{"laneID":1,"ingressApproach":1,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2215,"y":1218}}},{"delta":{"nodeXY6":{"x":10451,"y":-223}},"attributes":{"dElevation":-70}},{"delta":{"nodeXY6":{"x":1852,"y":-108}},"attributes":{"dElevation":-10}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":28,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"laneID":4,"ingressApproach":1,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2213,"y":-124}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":7187,"y":20}},"attributes":{"dElevation":-40}},{"delta":{"nodeXY6":{"x":541,"y":40}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":1298,"y":229}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":12,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":7,"connectionID":1}]}},{"laneID":6,"egressApproach":2,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2267,"y":-1019}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":365,"y":7}}}]}},{"laneID":5,"egressApproach":2,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2267,"y":-662}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":338,"y":0}}}]}},{"laneID":7,"egressApproach":2,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":2294,"y":-1463}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":365,"y":27}}}]}},{"laneID":12,"egressApproach":4,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-952,"y":-1898}}},{"delta":{"nodeXY6":{"x":0,"y":-377}}}]}},{"laneID":13,"egressApproach":4,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-1440,"y":-1898}}},{"delta":{"nodeXY6":{"x":7,"y":-390}}},{"delta":{"nodeXY6":{"x":0,"y":0}}},{"delta":{"nodeXY6":{"x":0,"y":7}}}]}},{"laneID":10,"ingressApproach":3,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":705,"y":-1919}}},{"delta":{"nodeXY6":{"x":-1,"y":-7515}},"attributes":{"dElevation":-40}},{"delta":{"nodeXY6":{"x":-41,"y":-5272}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-17,"y":-11337}}},{"delta":{"nodeXY6":{"x":17,"y":-5938}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":0,"y":0}}},{"delta":{"nodeXY6":{"x":-7,"y":-7}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":26,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":6,"connectionID":1}]}},{"laneID":9,"ingressApproach":3,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":1090,"y":-1930}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":9,"y":-4764}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":-20,"y":-6402}},"attributes":{"dElevation":-20}},{"delta":{"nodeXY6":{"x":-34,"y":-7953}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":16,"y":-10940}},"attributes":{"dElevation":20}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":27,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":6,"connectionID":1}]}},{"laneID":11,"ingressApproach":3,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":350,"y":-1925}}},{"delta":{"nodeXY6":{"x":-32,"y":-6698}},"attributes":{"dElevation":-30}},{"delta":{"nodeXY6":{"x":156,"y":-2616}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":18,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":1,"connectionID":1}]}},{"laneID":8,"ingressApproach":3,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":1557,"y":-1956}},"attributes":{"dElevation":-10}},{"delta":{"nodeXY6":{"x":-101,"y":-1956}}},{"delta":{"nodeXY6":{"x":-5,"y":-7393}},"attributes":{"dElevation":-40}},{"delta":{"nodeXY6":{"x":-121,"y":-1636}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":7,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"laneID":15,"ingressApproach":5,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2405,"y":-1018}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-9339,"y":26}},"attributes":{"dElevation":30}},{"delta":{"nodeXY6":{"x":-11895,"y":-38}},"attributes":{"dElevation":50}},{"delta":{"nodeXY6":{"x":-8814,"y":13}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":6,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":8,"connectionID":1}]}},{"laneID":16,"ingressApproach":5,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2337,"y":-656}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-12229,"y":15}},"attributes":{"dElevation":50}},{"delta":{"nodeXY6":{"x":-11362,"y":-37}},"attributes":{"dElevation":30}},{"delta":{"nodeXY6":{"x":-6537,"y":1}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":5,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":8,"connectionID":1}]}},{"laneID":17,"ingressApproach":5,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2338,"y":-284}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-8892,"y":-18}},"attributes":{"dElevation":30}},{"delta":{"nodeXY6":{"x":-11959,"y":-2}},"attributes":{"dElevation":50}},{"delta":{"nodeXY6":{"x":-1564,"y":-180}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":26,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":3,"connectionID":1}]}},{"laneID":14,"ingressApproach":5,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2401,"y":-1380}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-19947,"y":8}},"attributes":{"dElevation":80}},{"delta":{"nodeXY6":{"x":-10108,"y":-7}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":13,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"laneID":18,"egressApproach":6,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2264,"y":479}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":-580,"y":-14}}}]}},{"laneID":19,"egressApproach":6,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2257,"y":796}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":-518,"y":0}}}]}},{"laneID":20,"egressApproach":6,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-2236,"y":1229}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":-484,"y":0}}}]}},{"laneID":23,"ingressApproach":7,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-914,"y":1903}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":225,"y":12288}},"attributes":{"dElevation":30}},{"delta":{"nodeXY6":{"x":40,"y":9634}},"attributes":{"dElevation":-20}},{"delta":{"nodeXY6":{"x":32,"y":8035}},"attributes":{"dElevation":-30}},{"delta":{"nodeXY6":{"x":0,"y":0}}},{"delta":{"nodeXY6":{"x":-7,"y":28}}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":12,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":2,"connectionID":1}]}},{"laneID":22,"ingressApproach":7,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-1221,"y":1914}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":92,"y":10475}},"attributes":{"dElevation":30}},{"delta":{"nodeXY6":{"x":89,"y":11582}},"attributes":{"dElevation":-20}},{"delta":{"nodeXY6":{"x":48,"y":7912}},"attributes":{"dElevation":-30}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":13,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":2,"connectionID":1}]}},{"laneID":21,"ingressApproach":7,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-1649,"y":1935}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":16,"y":3182}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":21,"y":5991}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":102,"y":4810}}},{"delta":{"nodeXY6":{"x":85,"y":11803}},"attributes":{"dElevation":-30}},{"delta":{"nodeXY6":{"x":19,"y":4161}},"attributes":{"dElevation":-20}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":20,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"laneID":24,"ingressApproach":7,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-535,"y":1926}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":28,"y":4582}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":88,"y":3793}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-143,"y":1866}},"attributes":{"dElevation":10}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":6,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":5,"connectionID":1}]}},{"laneID":25,"ingressApproach":7,"laneAttributes":{"directionalUse":{"ingressPath":true,"egressPath":false},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":-213,"y":1913}},"attributes":{"dElevation":20}},{"delta":{"nodeXY6":{"x":14,"y":4594}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-91,"y":2238}},"attributes":{"dElevation":10}}]},"connectsTo":{"connectsTo":[{"connectingLane":{"lane":5,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":5,"connectionID":1}]}},{"laneID":26,"egressApproach":8,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":724,"y":1902}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-7,"y":352}},"attributes":{"dElevation":10}}]}},{"laneID":27,"egressApproach":8,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":1105,"y":1888}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-7,"y":332}},"attributes":{"dElevation":10}}]}},{"laneID":28,"egressApproach":8,"laneAttributes":{"directionalUse":{"ingressPath":false,"egressPath":true},"shareWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}}},"nodeList":{"nodes":[{"delta":{"nodeXY6":{"x":1591,"y":1874}},"attributes":{"dElevation":10}},{"delta":{"nodeXY6":{"x":-14,"y":346}}},{"delta":{"nodeXY6":{"x":0,"y":7}}}]}}]}}]}},"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735MAP"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-psm.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-psm.json new file mode 100644 index 000000000..035b14986 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-psm.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"psmTx","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdePsmPayload","serialId":{"streamId":"9219cf4d-66e3-4b65-8981-b56b50688023","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:33:49.421Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"UNKNOWN","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"00201A0000021BD86891DE75F84DA101C13F042E2214141FFF00022C2000270000000163B2CC79860100","psmSource":"RSU","originIp":"172.18.0.1"},"payload":{"data":{"basicType":"aPEDESTRIAN","secMark":3564,"msgCnt":26,"id":"24779D7E","position":{"latitude":40.2397377,"longitude":-74.2761437},"accuracy":{"semiMajor":1.00,"semiMinor":1.00,"orientation":44.9951935489},"speed":0,"heading":8898},"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735PSM"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-spat.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-spat.json new file mode 100644 index 000000000..366dbb3c8 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-spat.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"spatTx","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeSpatPayload","serialId":{"streamId":"a80d7125-d548-4114-b435-ce890b8906d3","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:34:40.359Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001338000817A780000089680500204642B342B34802021A15A955A940181190ACD0ACD20100868555C555C00104342AAE2AAE002821A15571557000","spatSource":"RSU","originIp":"172.18.0.1","isCertPresent":false},"payload":{"data":{"intersectionStateList":{"intersectionStatelist":[{"id":{"id":12111},"revision":0,"status":{"failureFlash":false,"noValidSPATisAvailableAtThisTime":false,"fixedTimeOperation":false,"standbyOperation":false,"trafficDependentOperation":false,"manualControlIsEnabled":false,"off":false,"stopTimeIsActivated":false,"recentChangeInMAPassignedLanesIDsUsed":false,"recentMAPmessageUpdate":false,"failureMode":false,"noValidMAPisAvailableAtThisTime":false,"signalPriorityIsActive":false,"preemptIsActive":false},"timeStamp":35176,"states":{"movementList":[{"signalGroup":2,"state_time_speed":{"movementEventList":[{"eventState":"PROTECTED_MOVEMENT_ALLOWED","timing":{"minEndTime":22120,"maxEndTime":22121}}]}},{"signalGroup":4,"state_time_speed":{"movementEventList":[{"eventState":"STOP_AND_REMAIN","timing":{"minEndTime":22181,"maxEndTime":22181}}]}},{"signalGroup":6,"state_time_speed":{"movementEventList":[{"eventState":"PROTECTED_MOVEMENT_ALLOWED","timing":{"minEndTime":22120,"maxEndTime":22121}}]}},{"signalGroup":8,"state_time_speed":{"movementEventList":[{"eventState":"STOP_AND_REMAIN","timing":{"minEndTime":21852,"maxEndTime":21852}}]}},{"signalGroup":1,"state_time_speed":{"movementEventList":[{"eventState":"STOP_AND_REMAIN","timing":{"minEndTime":21852,"maxEndTime":21852}}]}},{"signalGroup":5,"state_time_speed":{"movementEventList":[{"eventState":"STOP_AND_REMAIN","timing":{"minEndTime":21852,"maxEndTime":21852}}]}}]}}]}},"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735SPAT"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-srm.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-srm.json new file mode 100644 index 000000000..7cfa207c2 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-srm.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"srmTx","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeSrmPayload","serialId":{"streamId":"48e23a19-c438-4e97-a54e-150cdf10afe1","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:35:36.923Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"OBU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001D2130000010090BD341080D00855C6C0C6899853000A534F7C24CB29897694759B7C000","originIp":"172.18.0.1","srmSource":"RSU"},"payload":{"data":{"second":0,"sequenceNumber":1,"requests":{"signalRequestPackage":[{"request":{"id":{"id":12109},"requestID":4,"requestType":"priorityRequest","inBoundLane":{"lane":13},"outBoundLane":{"lane":4}},"duration":10979}]},"requestor":{"id":{"stationID":2366845094},"type":{"role":"publicTransport"},"position":{"position":{"latitude":39.5904915,"longitude":-105.0913829,"elevation":1685.4},"heading":175.9000}}},"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735SRM"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-ssm.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-ssm.json new file mode 100644 index 000000000..f8e77af81 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-ssm.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"ssmTx","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeSsmPayload","serialId":{"streamId":"b04f6d45-d1f2-4cfb-8a6c-f542bbd0aa51","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:36:31.804Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001E120000000005E9C04071A26614C06000040BA000","originIp":"172.18.0.1","ssmSource":"RSU"},"payload":{"data":{"second":0,"status":{"signalStatus":[{"sequenceNumber":0,"id":{"id":12110},"sigStatus":{"signalStatusPackage":[{"requester":{"id":{"stationID":2366845094},"request":3,"sequenceNumber":0,"typeData":{"role":"publicTransport"}},"inboundOn":{"lane":23},"status":"granted"}]}}]}},"dataType":"us.dot.its.jpo.ode.plugin.j2735.J2735SSM"}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim-specific.xml b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim-specific.xml new file mode 100644 index 000000000..fadc9ccb2 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim-specific.xml @@ -0,0 +1,214 @@ + + + + + dnMsg + success + + + + unsecuredData + MessageFrame + UPER + + + us.dot.its.jpo.ode.model.OdeAsn1Payload + + d1475b66-9f6d-4a85-a4bd-bc54a825fb0f + 1 + 0 + 0 + 0 + + 2024-12-10T17:20:48.699Z + 7 + 0 + + RSU + false + + + + 03810040038081D4001F80D07016DA410000000000000BBC2B0F775D9B0309C271431FA166EE0A27FFF93F136B8205A0A107FB2EF979F4C5BFAEEC97E4AD70C2FB36CD9730BECDB355CC2FD2A7556B160B98B46AB98AE62C185FA55EFB468D5B4000000004E2863F42CDDC144FF7980040401262CDD7B809C509F5C62CDD35519C507B9062CDCEE129C505CF262CDCA5FF9C50432C62CDC5D3D9C502E3E62CDC13E79C501E9262CDBCA2D9C5013EE62CDB80359C500E6A62CDB36299C500BC862CDAEC1D9C50093C62CDAA2109C5006EA1080203091A859EEEBB36006001830001AAD27F4FF7580001AAD355E39B5880A30029D6585009EF808332D8D9F80C3855151B38C772F765007967EC1170BCB7937F5CB880A25A52863493BCB87570DBCB5ABC6BFB2FAEC606CFA34EB95A24790B2017366D3AABE7729E00 + + 172.18.0.1 + + + MessageFrame + + + 31 + + + 1 + 449089 + 0000000000000BBC2B + null + + + 1 + + + + + + + 411269876 + -1047269563 + + 1111111111111111 + + + + + + 2018 + 448260 + 1440 + 5 + 1 + + + westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456 + + 0 + 0 + + + 411269876 + -1047269563 + + 32700 + + + + + + + 0000000000010000 + + + 0 + + + + + + + -1047287423 + 411264686 + + + + + + + -1047305390 + 411260104 + + + + + + + -1047323629 + 411256185 + + + + + + + -1047342080 + 411252886 + + + + + + + -1047360706 + 411250207 + + + + + + + -1047379480 + 411248201 + + + + + + + -1047398354 + 411246839 + + + + + + + -1047417290 + 411246133 + + + + + + + -1047436246 + 411245796 + + + + + + + -1047455202 + 411245470 + + + + + + + -1047474159 + 411245173 + + + + + + + + + + + 1 + 1 + + + + + 777 + + + + + 13579 + + + + + null + + + + + + + + \ No newline at end of file diff --git a/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim.json b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim.json new file mode 100644 index 000000000..4302c7c70 --- /dev/null +++ b/jpo-ode-svcs/src/test/resources/us/dot/its/jpo/ode/services/asn1/expected-tim.json @@ -0,0 +1 @@ +{"metadata":{"logFileName":"","recordType":"dnMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"d1475b66-9f6d-4a85-a4bd-bc54a825fb0f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-10T17:20:48.699Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"03810040038081D4001F80D07016DA410000000000000BBC2B0F775D9B0309C271431FA166EE0A27FFF93F136B8205A0A107FB2EF979F4C5BFAEEC97E4AD70C2FB36CD9730BECDB355CC2FD2A7556B160B98B46AB98AE62C185FA55EFB468D5B4000000004E2863F42CDDC144FF7980040401262CDD7B809C509F5C62CDD35519C507B9062CDCEE129C505CF262CDCA5FF9C50432C62CDC5D3D9C502E3E62CDC13E79C501E9262CDBCA2D9C5013EE62CDB80359C500E6A62CDB36299C500BC862CDAEC1D9C50093C62CDAA2109C5006EA1080203091A859EEEBB36006001830001AAD27F4FF7580001AAD355E39B5880A30029D6585009EF808332D8D9F80C3855151B38C772F765007967EC1170BCB7937F5CB880A25A52863493BCB87570DBCB5ABC6BFB2FAEC606CFA34EB95A24790B2017366D3AABE7729E00","originIp":"172.18.0.1"},"payload":{"data":{"msgCnt":1,"timeStamp":449089,"packetID":"0000000000000BBC2B","urlB":"null","dataFrames":[{"notUsed":1,"frameType":"advisory","msgId":{"roadSignID":{"position":{"lat":411269876,"long":-1047269563},"viewAngle":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":true,"from045-0to067-5degrees":true,"from067-5to090-0degrees":true,"from090-0to112-5degrees":true,"from112-5to135-0degrees":true,"from135-0to157-5degrees":true,"from157-5to180-0degrees":true,"from180-0to202-5degrees":true,"from202-5to225-0degrees":true,"from225-0to247-5degrees":true,"from247-5to270-0degrees":true,"from270-0to292-5degrees":true,"from292-5to315-0degrees":true,"from315-0to337-5degrees":true,"from337-5to360-0degrees":true},"mutcdCode":"warning"}},"startYear":2018,"startTime":448260,"durationTime":1440,"priority":5,"notUsed1":1,"regions":[{"name":"westbound_I-80_366.0_365.0_RSU-10.145.1.100_RW_4456","id":{"region":0,"id":0},"anchor":{"lat":411269876,"long":-1047269563},"laneWidth":32700,"directionality":"both","closedPath":false,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":true,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":0,"offset":{"xy":{"nodes":[{"delta":{"node-LatLon":{"lon":-1047287423,"lat":411264686}}},{"delta":{"node-LatLon":{"lon":-1047305390,"lat":411260104}}},{"delta":{"node-LatLon":{"lon":-1047323629,"lat":411256185}}},{"delta":{"node-LatLon":{"lon":-1047342080,"lat":411252886}}},{"delta":{"node-LatLon":{"lon":-1047360706,"lat":411250207}}},{"delta":{"node-LatLon":{"lon":-1047379480,"lat":411248201}}},{"delta":{"node-LatLon":{"lon":-1047398354,"lat":411246839}}},{"delta":{"node-LatLon":{"lon":-1047417290,"lat":411246133}}},{"delta":{"node-LatLon":{"lon":-1047436246,"lat":411245796}}},{"delta":{"node-LatLon":{"lon":-1047455202,"lat":411245470}}},{"delta":{"node-LatLon":{"lon":-1047474159,"lat":411245173}}}]}}}}}],"notUsed2":1,"notUsed3":1,"content":{"advisory":[{"item":{"itis":777}},{"item":{"itis":13579}}]},"url":"null"}]},"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation"}} \ No newline at end of file From 43e0333cd586fa24bc4687cd1e52555da228acaf Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Fri, 13 Dec 2024 16:37:54 -0700 Subject: [PATCH 153/264] Finishing addressing merge conflicts in TIM_test.json, TimDepositController.java & TimTransmogrifierTest.java Signed-off-by: dmccoystephenson --- .../src/test/resources/CVMessages/TIM_test.json | 2 +- .../its/jpo/ode/traveler/TimDepositController.java | 4 +--- .../its/jpo/ode/traveler/TimTransmogrifierTest.java | 12 ++++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json index 3e096b913..f51802404 100644 --- a/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json +++ b/jpo-ode-core/src/test/resources/CVMessages/TIM_test.json @@ -1 +1 @@ -{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"notUsed":29,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"notUsed1":1,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"notUsed2":15,"notUsed3":9,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"notUsed":11,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"notUsed1":10,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"notUsed2":11,"notUsed3":23,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"notUsed":13,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"notUsed1":6,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"notUsed2":31,"notUsed3":12,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file +{"metadata":{"logFileName":"","recordType":"timMsg","securityResultCode":"success","receivedMessageDetails":{"rxSource":"NA"},"payloadType":"us.dot.its.jpo.ode.model.OdeTimPayload","serialId":{"streamId":"8af76b08-89bf-422e-b674-0f0ee065666f","bundleSize":1,"bundleId":0,"recordId":0,"serialNumber":0},"odeReceivedAt":"2024-12-06T10:39:42.806Z","schemaVersion":7,"maxDurationTime":0,"recordGeneratedAt":"","recordGeneratedBy":"RSU","sanitized":false,"odePacketID":"","odeTimStartDateTime":"","asn1":"001F830A752544F94F4354455420535452124C16B4FA27D64F431A94AC28F232828FF05260B5CA82DDFB227A687CA09CFDE87C4B0ED1C8800280204A865BB2C265D1E4F5D3A877C07F8093FC3D820142C4EB15C7AC09CE3356F45A90200118358186A148D3F13220B227C18569099E2D1232A28B5F2579208E479151D45D438BEFF80DB0C08CED3F45A50103103102088C1A44A152889AFA7F62218940E831C20F35EA1232777BF31146022C71408809E5EB7BA1D52835D8A040D83367520C4AB397658B07E21393A041060D049E825C15FCF56AFF05260B58E40024126EDBD550F6D519709FDE4CF880201602008CEE4ACA5DE274975513846DD7AD77F839305AD383175AA8A497954C284E668FFE4F0710D80802810030EAC2535BCD6AE047899B1CE75405C8E6936419C672A85F8900C50B428CA3188CA4E1101B485DEE47349B20CE339542FC5654852A1484C9C0A0B6DEBB81DB91CD26C8338CE550BF31188B6041101F08134A407147800DFCF8E5FE0A4C16B2BF3A3A253269429B3B8198F71B71F8C902002C008005DD1174A86649950714134C54C82F4C0012B9C982D69B5BEADBF1C99BEFD660C6A4200201A7A1ECCA540B60B0AA27F8093AC4BF831472A28ECD2E0203575E8F15F5000818817507D68CC505CF4497E8219CA2288A03C81503120AEB852B7507D68CC505CF4497E2121346A090E8061520293D37841E41530E9BF4214E93C326CF8502830F0C081FF9D71FE064C1BAA780A12351A24D300B6FD25F085703880101600022BE028AC1105C1D5CB0F0E001A42F7F849305AD3E9B408EB43464DC861E6234918C8667857300022C400087E511D765E294CF3507435289D7EBBC2849A4982D69F494982D524C16B4FA36827A1D6C31DFDBE55A627F819307EA49F19AA77C773D119EA690CE094883E0100588001E1832A00950E876B85589726EF3EDFE0E4C16B4F8EB0ECDE8A23F3F9E839831CE316170D2000858080178162BF959EDACD55B2CD3721A1EDFE064C1AEC1B3F02442FEC92E119DFAF82D6EC3884002C0004A9FEDD617613A307F791C6D74FB1A27C451F6139305AD394982D582367260B5A600","originIp":"172.18.0.1"},"payload":{"dataType":"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation","data":{"msgCnt":82,"timeStamp":345337,"packetID":"4F4354455420535452","urlB":"IA5St","dataFrames":[{"doNotUse1":0,"frameType":"commercialSignage","msgId":{"furtherInfoID":"4F43"},"startYear":425,"startTime":306216,"durationTime":31001,"priority":2,"doNotUse2":0,"regions":[{"name":"IA5","id":{"region":38149,"id":48118},"anchor":{"lat":-567387419,"elevation":53848,"long":-1717691068},"laneWidth":15175,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":true,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":-686654332,"elevation":38736,"long":1616508908},"radius":3832,"units":"centimeter"}}}}},{"name":"I","id":{"region":64573,"id":33281},"anchor":{"lat":-714161321,"elevation":48475,"long":-1285139143},"laneWidth":26805,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":1,"offset":{"ll":{"nodes":[{"delta":{"node-LL4":{"lon":-127947,"lat":-120550}},"attributes":{"localNode":["downstreamStopLine","closedToTraffic"],"disabled":["adjacentParkingOnLeft","transitStopOnLeft","parallelParking","mergingLaneLeft","curbOnLeft"],"enabled":["midBlockCurbPresent","transitStopInLane","taperToCenterLine","lowCurbsPresent"],"data":[{"pathEndPointAngle":-8,"laneCrownPointLeft":35,"laneAngle":62,"speedLimits":[{"type":"truckMaxSpeed","speed":5822},{"type":"truckNightMaxSpeed","speed":3017}]}],"dWidth":162,"dElevation":424}},{"delta":{"node-LatLon":{"lon":-998896073,"lat":735850714}},"attributes":{"localNode":["hydrantPresent","safeIsland","closedToTraffic","stopLine","reserved"],"disabled":["loadingzoneOnRight","adjacentParkingOnRight","headInParking"],"enabled":["costToPark","mergingLaneLeft","midBlockCurbPresent","unEvenPavementPresent","curbOnLeft"],"data":[{"laneAngle":-82,"speedLimits":[{"type":"truckMinSpeed","speed":2097}]}],"dWidth":264,"dElevation":-269}},{"delta":{"node-LL4":{"lon":86161,"lat":20207}},"attributes":{"localNode":["roundedCapStyleA","divergePoint","roundedCapStyleB","reserved"],"disabled":["adjacentParkingOnLeft","adjacentBikeLaneOnRight"],"enabled":["headInParking","timeRestrictionsOnParking"],"data":[{"laneCrownPointCenter":-68}],"dWidth":245,"dElevation":247}},{"delta":{"node-LL1":{"lon":-172,"lat":525}},"attributes":{"localNode":["closedToTraffic","roundedCapStyleA"],"disabled":["partialCurbIntrusion"],"enabled":["adaptiveTimingPresent"],"dWidth":206,"dElevation":144}},{"delta":{"node-LL5":{"lon":-873243,"lat":1464496}},"attributes":{"localNode":["stopLine","downstreamStartNode"],"disabled":["taperToRight","doNotBlock"],"enabled":["bikeBoxInFront"],"data":[{"pathEndPointAngle":25,"laneAngle":137}],"dWidth":414,"dElevation":181}}]}}}}},{"name":"IA5","id":{"region":7296,"id":1154},"anchor":{"lat":29950376,"elevation":16367,"long":270580409},"laneWidth":4926,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor10000meters","laneWidth":26482,"circle":{"center":{"lat":598135630,"elevation":32186,"long":664850545},"radius":3930,"units":"mile"}}}},{"name":"IA5S","id":{"region":1582,"id":46417},"anchor":{"lat":-283655839,"elevation":57976,"long":-685153664},"laneWidth":7235,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":true,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor1000meters","area":{"shapePointSet":{"anchor":{"lat":581272185,"elevation":9059,"long":1108489970},"laneWidth":20085,"directionality":"forward","nodeList":{"nodes":[{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["mergePoint","reserved"],"disabled":["turnOutPointOnRight","adjacentParkingOnLeft","freeParking","costToPark"],"enabled":["costToPark","adjacentParkingOnRight"],"data":[{"laneCrownPointRight":4,"laneAngle":-167}],"dWidth":144,"dElevation":239}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["hydrantPresent","divergePoint"],"disabled":["freeParking","unEvenPavementPresent"],"enabled":["freeParking","adaptiveTimingPresent","taperToLeft"],"data":[{"speedLimits":[{"type":"vehiclesWithTrailersMaxSpeed","speed":3517}]}],"dWidth":-36,"dElevation":-453}},{"delta":{"node-LatLon":{"lon":-605370079,"lat":829743521}},"attributes":{"localNode":["roundedCapStyleA","downstreamStopLine","mergePoint","hydrantPresent"],"disabled":["doNotBlock","whiteLine","bikeBoxInFront","sharedBikeLane"],"enabled":["bikeBoxInFront","transitStopInLane","unEvenPavementPresent","adjacentBikeLaneOnRight"],"data":[{"pathEndPointAngle":-95,"laneAngle":60}],"dWidth":463,"dElevation":57}}]}}}}}},{"name":"IA5","id":{"region":11251,"id":41890},"anchor":{"lat":385181606,"elevation":46812,"long":1670812734},"laneWidth":16153,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useInstantlyOnly","laneWidth":6004,"circle":{"center":{"lat":-509239964,"elevation":9413,"long":772185922},"radius":1224,"units":"cm2-5"}}}}],"doNotUse3":0,"doNotUse4":0,"content":{"exitService":[{"item":{"itis":599}}]},"url":"IA5S"},{"doNotUse1":0,"frameType":"commercialSignage","msgId":{"roadSignID":{"position":{"lat":634998835,"elevation":50308,"long":313588249},"viewAngle":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":true,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"mutcdCode":"maintenance","crc":"4F43"}},"startYear":3481,"startTime":305174,"durationTime":24752,"priority":5,"doNotUse2":0,"regions":[{"name":"I","id":{"region":44107,"id":63537},"anchor":{"lat":-419185997,"elevation":51107,"long":-533287210},"laneWidth":25278,"directionality":"reverse","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":true,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"path":{"scale":8,"offset":{"ll":{"nodes":[{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["roundedCapStyleA","roundedCapStyleB","downstreamStartNode","divergePoint"],"disabled":["timeRestrictionsOnParking","sharedWithTrackedVehicle"],"enabled":["taperToCenterLine"],"data":[{"pathEndPointAngle":24,"laneCrownPointCenter":9}],"dWidth":225,"dElevation":-213}},{"delta":{"node-LatLon":{"lon":900792217,"lat":448269129}},"attributes":{"localNode":["stopLine","mergePoint"],"disabled":["rfSignalRequestPresent"],"enabled":["turnOutPointOnLeft","loadingzoneOnLeft","headInParking","adjacentParkingOnRight","safeIsland"],"data":[{"pathEndPointAngle":-109,"laneCrownPointRight":83}],"dWidth":-31,"dElevation":-482}},{"delta":{"node-LL1":{"lon":-1370,"lat":-1581}},"attributes":{"localNode":["mergePoint","divergePoint","downstreamStartNode","safeIsland"],"disabled":["adaptiveTimingPresent","partialCurbIntrusion","parallelParking","curbOnLeft","doNotBlock"],"enabled":["curbOnRight","sharedBikeLane"],"data":[{"laneCrownPointLeft":-121}],"dWidth":505,"dElevation":348}}]}}}}},{"name":"IA","id":{"region":30031,"id":322},"anchor":{"lat":-454547095,"elevation":59458,"long":353479827},"laneWidth":23566,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":true,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"extent":"useFor10meters","laneWidth":24321,"circle":{"center":{"lat":-539150408,"elevation":45059,"long":-814772254},"radius":1157,"units":"mile"}}}},{"name":"IA5St","id":{"region":46088,"id":60227},"anchor":{"lat":-476956537,"elevation":4505,"long":759386724},"laneWidth":28846,"directionality":"forward","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":true,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor100meters","laneWidth":8084,"circle":{"center":{"lat":-405703383,"elevation":9512,"long":-508985739},"radius":2519,"units":"mile"}}}}],"doNotUse3":0,"doNotUse4":0,"content":{"exitService":[{"item":{"text":"I"}},{"item":{"text":"IA5St"}},{"item":{"text":"IA5"}}]},"url":"IA5St"},{"doNotUse1":0,"frameType":"unknown","msgId":{"furtherInfoID":"4F43"},"startYear":2776,"startTime":408571,"durationTime":15957,"priority":5,"doNotUse2":0,"regions":[{"name":"IA","id":{"region":62756,"id":63693},"anchor":{"lat":424936826,"elevation":35858,"long":-1208779998},"laneWidth":18563,"directionality":"both","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":true,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":true,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor5000meters","laneWidth":17158,"circle":{"center":{"lat":442482548,"elevation":43319,"long":-804103995},"radius":1951,"units":"meter"}}}},{"name":"IA5S","id":{"region":51032,"id":30319},"anchor":{"lat":-559743245,"elevation":46636,"long":1697199162},"laneWidth":5901,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":true,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"geometry":{"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":true,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor500meters","laneWidth":28716,"circle":{"center":{"lat":707126893,"elevation":35728,"long":-77527193},"radius":3343,"units":"meter"}}}},{"name":"IA","id":{"region":23939,"id":26592},"anchor":{"lat":-328004279,"elevation":45419,"long":88284632},"laneWidth":15118,"directionality":"unavailable","closedPath":true,"direction":{"from000-0to022-5degrees":false,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":true,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"description":{"oldRegion":{"direction":{"from000-0to022-5degrees":true,"from022-5to045-0degrees":false,"from045-0to067-5degrees":false,"from067-5to090-0degrees":false,"from090-0to112-5degrees":false,"from112-5to135-0degrees":false,"from135-0to157-5degrees":false,"from157-5to180-0degrees":false,"from180-0to202-5degrees":false,"from202-5to225-0degrees":false,"from225-0to247-5degrees":false,"from247-5to270-0degrees":false,"from270-0to292-5degrees":false,"from292-5to315-0degrees":false,"from315-0to337-5degrees":false,"from337-5to360-0degrees":false},"extent":"useFor50000meters","area":{"circle":{"center":{"lat":171361070,"elevation":57912,"long":1462406911},"radius":3502,"units":"kilometer"}}}}}],"doNotUse3":0,"doNotUse4":0,"content":{"speedLimit":[{"item":{"itis":40721}},{"item":{"itis":36784}},{"item":{"text":"IA5S"}},{"item":{"text":"IA5"}},{"item":{"itis":49435}}]},"url":"IA5S"}]}}} \ No newline at end of file diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 0d2900a13..46106bdba 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -34,7 +34,6 @@ import org.springframework.web.bind.annotation.RestController; import us.dot.its.jpo.ode.coder.OdeTimDataCreatorHelper; import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; -import us.dot.its.jpo.ode.kafka.OdeKafkaProperties; import us.dot.its.jpo.ode.kafka.topics.Asn1CoderTopics; import us.dot.its.jpo.ode.kafka.topics.JsonTopics; import us.dot.its.jpo.ode.kafka.topics.PojoTopics; @@ -314,8 +313,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); // publish Broadcast TIM to a J2735 compliant topic. stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - // publish J2735 TIM also to general un-filtered TIM topic - with streamID as key + // publish J2735 TIM also to general un-filtered TIM topic with streamID as key stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim);// Write XML to the encoder input topic at the end to ensure the correct order // of operations to pair // each message to an OdeTimJson streamId key diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java index 34ccfd7cd..b0d6fb5a2 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimTransmogrifierTest.java @@ -8,6 +8,18 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Clock; +import java.time.Instant; +import java.time.ZoneId; +import java.util.Date; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; From 05108c5865ec521474cd2e6661ee9072348dfccb Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Mon, 16 Dec 2024 09:01:29 -0700 Subject: [PATCH 154/264] Addressed checkstyle warnings in TimDepositController & TimDepositControllerTest Signed-off-by: dmccoystephenson --- .../ode/traveler/TimDepositController.java | 56 +++++++++---------- .../traveler/TimDepositControllerTest.java | 2 +- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java index 46106bdba..c7a238c0c 100644 --- a/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java +++ b/jpo-ode-svcs/src/main/java/us/dot/its/jpo/ode/traveler/TimDepositController.java @@ -103,11 +103,11 @@ public TimDepositControllerException(String errMsg) { */ @Autowired public TimDepositController(OdeKafkaProperties odeKafkaProperties, - Asn1CoderTopics asn1CoderTopics, - PojoTopics pojoTopics, - JsonTopics jsonTopics, - TimIngestTrackerProperties ingestTrackerProperties, - SecurityServicesProperties securityServicesProperties) { + Asn1CoderTopics asn1CoderTopics, + PojoTopics pojoTopics, + JsonTopics jsonTopics, + TimIngestTrackerProperties ingestTrackerProperties, + SecurityServicesProperties securityServicesProperties) { super(); this.asn1CoderTopics = asn1CoderTopics; @@ -120,7 +120,7 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, MessageProducer.defaultStringMessageProducer(odeKafkaProperties.getBrokers(), odeKafkaProperties.getKafkaType(), odeKafkaProperties.getDisabledTopics()); this.timProducer = new MessageProducer<>(odeKafkaProperties.getBrokers(), - odeKafkaProperties.getKafkaType(),null, + odeKafkaProperties.getKafkaType(), null, OdeTimSerializer.class.getName(), odeKafkaProperties.getDisabledTopics()); this.dataSigningEnabledSDW = securityServicesProperties.getIsSdwSigningEnabled(); @@ -131,7 +131,7 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, ScheduledExecutorService scheduledExecutorService = Executors - .newSingleThreadScheduledExecutor(); + .newSingleThreadScheduledExecutor(); scheduledExecutorService.scheduleAtFixedRate( new TimIngestWatcher(ingestTrackerProperties.getInterval()), @@ -144,10 +144,10 @@ public TimDepositController(OdeKafkaProperties odeKafkaProperties, } /** - * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST + * Send a TIM with the appropriate deposit type, ODE.PUT or ODE.POST. * * @param jsonString The value of the JSON message - * @param verb The HTTP verb being requested + * @param verb The HTTP verb being requested * @return The request completion status */ public synchronized ResponseEntity depositTim(String jsonString, RequestVerb verb) { @@ -157,7 +157,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request log.error(errMsg); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } OdeTravelerInputData odeTID; @@ -166,14 +166,14 @@ public synchronized ResponseEntity depositTim(String jsonString, Request // Convert JSON to POJO odeTID = (OdeTravelerInputData) JsonUtils.jacksonFromJson(jsonString, - OdeTravelerInputData.class, + OdeTravelerInputData.class, true); if (odeTID == null) { String errMsg = "Malformed or non-compliant JSON syntax."; log.error(errMsg); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } request = odeTID.getRequest(); @@ -192,13 +192,13 @@ public synchronized ResponseEntity depositTim(String jsonString, Request log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } catch (JsonUtilsException e) { String errMsg = "Malformed or non-compliant JSON syntax."; log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } // Add metadata to message and publish to kafka @@ -237,13 +237,13 @@ public synchronized ResponseEntity depositTim(String jsonString, Request try { timMetadata.setRecordGeneratedAt( DateTimeUtils.isoDateTime( - DateTimeUtils.isoDateTime(tim.getTimeStamp()))); + DateTimeUtils.isoDateTime(tim.getTimeStamp()))); } catch (DateTimeParseException e) { String errMsg = "Invalid timestamp in tim record: " + tim.getTimeStamp(); log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } OdeTimData odeTimData = new OdeTimData(timMetadata, timDataPayload); @@ -285,7 +285,7 @@ public synchronized ResponseEntity depositTim(String jsonString, Request log.error(errMsg, e); return ResponseEntity.status(HttpStatus.BAD_REQUEST) .body( - JsonUtils.jsonKeyValue(ERRSTR, errMsg)); + JsonUtils.jsonKeyValue(ERRSTR, errMsg)); } try { @@ -297,24 +297,24 @@ public synchronized ResponseEntity depositTim(String jsonString, Request asd = TimTransmogrifier.buildASD(odeTID.getRequest()); } xmlMsg = TimTransmogrifier.convertToXml(asd, encodableTid, timMetadata, serialIdJ2735); -if (xmlMsg != null) { + if (xmlMsg != null) { log.debug("XML representation: {}", xmlMsg); - // Convert XML into ODE TIM JSON object and obfuscate RSU password + // Convert XML into ODE TIM JSON object and obfuscate RSU password OdeTimData odeTimObj = OdeTimDataCreatorHelper.createOdeTimDataFromCreator( xmlMsg, timMetadata); - String j2735Tim = - odeTimObj - .toString(); + String j2735Tim = + odeTimObj + .toString(); - - String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); - // publish Broadcast TIM to a J2735 compliant topic. - stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); - // publish J2735 TIM also to general un-filtered TIM topic with streamID as key - stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), obfuscatedJ2735Tim);// Write XML to the encoder input topic at the end to ensure the correct order + String obfuscatedJ2735Tim = TimTransmogrifier.obfuscateRsuPassword(j2735Tim); + // publish Broadcast TIM to a J2735 compliant topic. + stringMsgProducer.send(jsonTopics.getJ2735TimBroadcast(), null, obfuscatedJ2735Tim); + // publish J2735 TIM also to general un-filtered TIM topic with streamID as key + stringMsgProducer.send(jsonTopics.getTim(), serialIdJ2735.getStreamId(), + obfuscatedJ2735Tim); // Write XML to the encoder input topic at the end to ensure the correct order // of operations to pair // each message to an OdeTimJson streamId key stringMsgProducer.send(asn1CoderTopics.getEncoderInput(), null, xmlMsg); diff --git a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java index b6c3d50b8..53ba2bead 100644 --- a/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java +++ b/jpo-ode-svcs/src/test/java/us/dot/its/jpo/ode/traveler/TimDepositControllerTest.java @@ -213,7 +213,7 @@ void testSuccessfulTimIngestIsTracked( // This serves as an integration test without mocking the TimTransmogrifier and XmlUtils@Test void testSuccessfulRsuMessageReturnsSuccessMessagePost( - ) { + ) { String timToSubmit = "{\"request\": {\"rsus\": [{\"latitude\": 30.123456, \"longitude\": -100.12345, \"rsuId\": 123, \"route\": \"myroute\", \"milepost\": 10, \"rsuTarget\": \"172.0.0.1\", \"rsuRetries\": 3, \"rsuTimeout\": 5000, \"rsuIndex\": 7, \"rsuUsername\": \"myusername\", \"rsuPassword\": \"mypassword\"}], \"snmp\": {\"rsuid\": \"83\", \"msgid\": 31, \"mode\": 1, \"channel\": 183, \"interval\": 2000, \"deliverystart\": \"2024-05-13T14:30:00Z\", \"deliverystop\": \"2024-05-13T22:30:00Z\", \"enable\": 1, \"status\": 4}}, \"tim\": {\"msgCnt\": \"1\", \"timeStamp\": \"2024-05-10T19:01:22Z\", \"packetID\": \"123451234512345123\", \"urlB\": \"null\", \"dataframes\": [{\"startDateTime\": \"2024-05-13T20:30:05.014Z\", \"durationTime\": \"30\", \"doNotUse1\": 0, \"frameType\": \"advisory\", \"msgId\": {\"roadSignID\": {\"mutcdCode\": \"warning\", \"viewAngle\": \"1111111111111111\", \"position\": {\"latitude\": 30.123456, \"longitude\": -100.12345}}}, \"priority\": \"5\", \"doNotUse2\": 0, \"regions\": [{\"name\": \"I_myroute_RSU_172.0.0.1\", \"anchorPosition\": {\"latitude\": 30.123456, \"longitude\": -100.12345}, \"laneWidth\": \"50\", \"directionality\": \"3\", \"closedPath\": \"false\", \"description\": \"path\", \"path\": {\"scale\": 0, \"nodes\": [{\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}, {\"delta\": \"node-LL\", \"nodeLat\": 0.0, \"nodeLong\": 0.0}], \"type\": \"ll\"}, \"direction\": \"0000000000010000\"}], \"doNotUse4\": 0, \"doNotUse3\": 0, \"content\": \"workZone\", \"items\": [\"771\"], \"url\": \"null\"}]}}"; ResponseEntity actualResponse = testTimDepositController.postTim(timToSubmit); From bac7f0a57568653e2d9a626ae492a2a0a8209c00 Mon Sep 17 00:00:00 2001 From: Drew Johnston <31270488+drewjj@users.noreply.github.com> Date: Mon, 16 Dec 2024 10:09:08 -0700 Subject: [PATCH 155/264] Update POM version --- jpo-ode-common/pom.xml | 2 +- jpo-ode-core/pom.xml | 6 +++--- jpo-ode-plugins/pom.xml | 4 ++-- pom.xml | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jpo-ode-common/pom.xml b/jpo-ode-common/pom.xml index 7ba82c8d5..e91045b8f 100644 --- a/jpo-ode-common/pom.xml +++ b/jpo-ode-common/pom.xml @@ -5,7 +5,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT jpo-ode-common diff --git a/jpo-ode-core/pom.xml b/jpo-ode-core/pom.xml index 638e02106..fe0b49f86 100644 --- a/jpo-ode-core/pom.xml +++ b/jpo-ode-core/pom.xml @@ -5,7 +5,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT jpo-ode-core @@ -23,12 +23,12 @@ usdot.jpo.ode jpo-ode-common - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT usdot.jpo.ode jpo-ode-plugins - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT org.apache.httpcomponents diff --git a/jpo-ode-plugins/pom.xml b/jpo-ode-plugins/pom.xml index 50b5281d1..485792bc7 100644 --- a/jpo-ode-plugins/pom.xml +++ b/jpo-ode-plugins/pom.xml @@ -11,7 +11,7 @@ usdot.jpo.ode jpo-ode - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT @@ -27,7 +27,7 @@ usdot.jpo.ode jpo-ode-common - 3.0.0-SNAPSHOT + 4.0.0-SNAPSHOT @@ -27,7 +27,7 @@ usdot.jpo.ode jpo-ode-common - 4.0.0-SNAPSHOT + 4.0.0 >_=nS7gnK{sa58we>t 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�m7ft9;L5H1jWjUIlf1PG`tLlv`Rp~%AAnH) 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 |4J*DeFM%6jXDM+ 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/data-flow-diagrams/bsm/BSM Data Flow.drawio.png b/docs/data-flow-diagrams/bsm/BSM Data Flow.drawio.png index 2b51b350e47b79a597bc1a9ff49af58f5f4373d2..e854b72d5f6a81d5cc95037c02d8926a9020a119 100644 GIT binary patch literal 151495 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

6LEOkYs1HMuj@ouXNZ1& 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 literal 95336 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

O_R#qPb4&o{cyU`Cncyf%c{&w~;7 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/data-flow-diagrams/spat/SPAT Data Flow.drawio.png b/docs/data-flow-diagrams/spat/SPAT Data Flow.drawio.png index 8741be56f59991ecfe26ce4d95fa364449c1f91c..df803f65f7914afb13e6dc89cd743aa1ee8a5634 100644 GIT binary patch literal 150377 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�csTP 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 literal 171439 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≫jjj}XpzC_7Y%h=7=z0+z!dhmXnj>Ru- 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 S43i7skFtXLgF-orSN{*-_qjI! diff --git a/docs/data-flow-diagrams/srm/SRM Data Flow.drawio b/docs/data-flow-diagrams/srm/SRM Data Flow.drawio deleted file mode 100644 index 7a1facd07..000000000 --- a/docs/data-flow-diagrams/srm/SRM Data Flow.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/data-flow-diagrams/srm/SRM Data Flow.drawio.png b/docs/data-flow-diagrams/srm/SRM Data Flow.drawio.png index 7c1d733cd07671173ecfd3f34846c9066abe37d3..bf0ab84d0e8eb62424a510249734f3b87ddbdc56 100644 GIT binary patch literal 89989 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

D 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

a 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 D=zRk} diff --git a/docs/data-flow-diagrams/ssm/SSM Data Flow.drawio b/docs/data-flow-diagrams/ssm/SSM Data Flow.drawio deleted file mode 100644 index da722a3a6..000000000 --- a/docs/data-flow-diagrams/ssm/SSM Data Flow.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/data-flow-diagrams/ssm/SSM Data Flow.drawio.png b/docs/data-flow-diagrams/ssm/SSM Data Flow.drawio.png index 7e5c31e1a6cca7a7a8113084cba7c815c5e263d5..4873a1cef7d827df01ebb6d7172eded4262c3e6d 100644 GIT binary patch literal 92887 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

hA)!!O)|I?f*P0ruGGBvQZ3Dp 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

}Z- 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 diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio deleted file mode 100644 index 06dffdb67..000000000 --- a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio +++ /dev/null @@ -1,364 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png b/docs/data-flow-diagrams/tim/TIM Data Flow.drawio.png index 7ab094559ba18e455c8bc828a550a52fab8d05df..72df963a67a3ebbe08734ca3137331acabb5fb88 100644 GIT binary patch literal 262631 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

m|=;4H{mMI;x;i#m<5zk=Cneh_=?w**&(JiH&@ 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

61Jr+K~-Gz6&ejX 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 z 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 E0S>WVP5=M^ diff --git a/docs/data-flow-diagrams/map/MAP Data Flow.drawio b/docs/data-flow-diagrams/map/MAP Data Flow.drawio deleted file mode 100644 index a4e70d1a2..000000000 --- a/docs/data-flow-diagrams/map/MAP Data Flow.drawio +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/data-flow-diagrams/map/MAP Data Flow.drawio.png b/docs/data-flow-diagrams/map/MAP Data Flow.drawio.png index 1803fc5576a132e90d9ef675b9329cf9115ea4c2..977ddef81fa2a7bf23378f42d495c273d8a9aba3 100644 GIT binary patch literal 139345 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 z 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%0Ac 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 W7&uiAd~pr<^XjFHNd6105B~#UOPs_2 literal 147245 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 diff --git a/docs/data-flow-diagrams/psm/PSM Data Flow.drawio b/docs/data-flow-diagrams/psm/PSM Data Flow.drawio deleted file mode 100644 index 64aca0d5c..000000000 --- a/docs/data-flow-diagrams/psm/PSM Data Flow.drawio +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file diff --git a/docs/data-flow-diagrams/psm/PSM Data Flow.drawio.png b/docs/data-flow-diagrams/psm/PSM Data Flow.drawio.png index 9203886ae79d57b731cabd377b47ed68563887b3..7f6faf57d6f1b84e0d36aa243f0a6b14c5c565e2 100644 GIT binary patch literal 91756 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